для части школьной лаборатории мне нужно читать уникальные слова и их соответствующий счет со структурой. Я новичок в структурах, поэтому, пожалуйста, потерпите меня. Я получаю нарушение прав доступа, когда пытаюсь записать адрес текущего слова в указатель символа внутри текущего экземпляра моей структуры. Я читал, что это связано с разыменованием nullptr. Я пытался понять это, но я просто не понимаю. Я изменил размер массивов точно так же, как это на обычных массивах char ** для приема новых слов. Я в недоумении, любая помощь будет принята с благодарностью. Используемый здесь входной файл представляет собой просто случайные слова, разделенные небуквенными символами, но не - или. Вот мой код:
#define _CRT_SECURE_NO_WARNINGS
#define _CRTDBG_MAP_ALLOC
#include <iostream>
#include <iomanip>
#include <fstream>
#include <limits>
using std::cin;
using std::cout;
using std::endl;
using std::setw;
using std::right;
using std::left;
using std::ifstream;
using std::ofstream;
const int BUFFER = 100; //I figure this buffer is big enough for any given word
struct Word_Count_STRUCT
{
char* WORD = nullptr;
int COUNT = 0;
};
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
//Input for phrase
ifstream iphrase;
//Output to CSV (word count)
ofstream o_count;
//Word Exceptions
ifstream xinWord;
char wordbuffer[BUFFER] = { '\0' };
char ch = 0;
Word_Count_STRUCT** uniquewords = nullptr;
Word_Count_STRUCT** temp = nullptr;
int k = 0;
int wordcount = 0;
char* cword = nullptr; //Current Word
bool NextWord_flag = false;
bool interwordpunct = false;
bool NewWord_flag = true;
iphrase.open("C:\\Users\\me\\Desktop\\henroE.txt");
if (iphrase.is_open())
{
while (!iphrase.eof())
{
iphrase.get(ch);
if (isalpha(ch) || ch == '\'' || ch == '-')
{
wordbuffer[k] = ch;
++k;
NextWord_flag = true;
if (ch == '\'' || ch == '-')
interwordpunct = true;
}
if ( (NextWord_flag == true) && (!isalpha(ch)) && (interwordpunct == false) )
{
k = 0;
cword = new char[strlen(wordbuffer) + 1];
strcpy(cword, wordbuffer);
memset(wordbuffer, '\0', sizeof(wordbuffer));
for (int i = 0; (i < wordcount) && (NewWord_flag == true); ++i)
{
int cmp = _stricmp(uniquewords[i]->WORD, cword);
if (cmp == 0)
{
NewWord_flag = false;
uniquewords[i]->COUNT++;
delete[] cword;
}
}
if (NewWord_flag == true)
{
temp = new Word_Count_STRUCT * [wordcount + 1]();
for (int i = 0; i < wordcount; ++i)
{
temp[i] = uniquewords[i];
}
delete[] uniquewords;
temp[wordcount]->WORD = cword;
temp[wordcount]->COUNT++;
uniquewords = temp;
++wordcount;
NextWord_flag = false;
}
interwordpunct = false;
NewWord_flag = true;
}
}
}
Я получаю ошибку в этой строке:
temp[wordcount]->WORD = cword;
Я также получаю сообщение об ошибке в значении COUNT int, если я прокомментирую строку над ним. Итак, я предполагаю, что это что-то с тем, как я инициализировал структуру. Стоит отметить, что если я не инициализирую этот вызов:
temp = new Word_Count_STRUCT * [wordcount + 1]();
и вместо этого просто оставьте его как
temp = new Word_Count_STRUCT * [wordcount + 1];
Я получаю еще одно нарушение прав доступа, но для чтения вместо записи в 0xFFFFF...
В недоумении, спасибо за любую помощь :)
Мои извинения, я добавил заголовки, я вообще не уверен, где может возникнуть проблема, поэтому я не знаю, как ее уменьшить :(
Какова ценность wordcount
? Я ожидаю, что это ноль, иначе доступ к uniquewords
(который также равен нулю) не удастся раньше. temp[wordcount]
значение равно нулю. Пожалуйста, используйте отладчик и просмотрите свой код построчно, просматривая значения переменных по мере выполнения кода. У нас нет вашего исходного файла.
Один из подходов — создать резервную копию программы, а затем удалить ее половину. Скомпилируйте, запустите, посмотрите, есть ли у вас проблема. Если да, удалите половину того, что осталось, и повторите. Если не акцентировать внимание на удаленной половине. Это немного сложнее, чем буквально разрезать программу пополам, что почти наверняка не скомпилируется, но грубое логическое деление пополам по-прежнему является хорошим способом для начала.
Вы ошиблись во многих вещах. Во-первых, использование символьных буферов фиксированной длины вместо строк C++ устарело примерно на 20 лет и БУДЕТ вызывать ошибки переполнения буфера, если вы не будете предельно осторожны.
Но это вопрос:
temp = new Word_Count_STRUCT * [wordcount + 1]();
for (int i = 0; i < wordcount; ++i)
{
temp[i] = uniquewords[i];
}
delete[] uniquewords;
Но куда вы выделили уникальные слова? Вы это заявили.
Вы также выделяете cword вне цикла, но удаляете его внутри цикла, что тоже кажется очень подозрительным.
Но обратите внимание, что все, что вы выделили, это указатели. Я не вижу, чтобы вы на самом деле выделяли структуру, в которую пытаетесь поместить данные.
«Но обратите внимание, что все, что вы выделили, — это указатели. Я не вижу, чтобы вы на самом деле выделяли структуру, в которую пытаетесь поместить данные». Чувак, это смущает, я действительно не подумал об этом, теперь мой код работает, спасибо, сэр. Я бы очень хотел проголосовать за ваш ответ, но моя учетная запись слишком новая, чтобы сделать это. Спасибо!
Пожалуйста, сделайте минимальный воспроизводимый пример, включающий ваши заголовки. Не заставляйте нас гадать, как скомпилировать ваш код. Что такое несколько строк файла
henroE.txt
?