向结构体赋值时出现0x00000...写入访问违例的问题排查
问题根源与修复方案
核心错误
你定义的uniquewords和temp是结构体指针的数组,但你只扩容了指针数组的大小,却没有为新的指针分配实际的Word_Count_STRUCT实例。temp = new Word_Count_STRUCT * [wordcount + 1]();会把数组里的所有指针初始化为nullptr,直接访问temp[wordcount]->WORD就是解引用空指针,必然触发写入访问违例。
分步修复
为新结构体分配内存
当新增单词时,必须先给temp[wordcount]分配一个Word_Count_STRUCT对象,再赋值成员: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] = new Word_Count_STRUCT(); temp[wordcount]->WORD = cword; temp[wordcount]->COUNT++; uniquewords = temp; ++wordcount; NextWord_flag = false; }修复文件读取逻辑
while (!iphrase.eof())会导致最后一个字符被重复读取,改成while (iphrase.get(ch)),利用流的状态判断读取是否成功:if (iphrase.is_open()) { while (iphrase.get(ch)) // 替换原while (!iphrase.eof()) { // 原读取逻辑不变 } }防止缓冲区溢出
在向wordbuffer写入字符时,要检查k是否超过BUFFER-1(留一个位置存终止符):if (isalpha(ch) || ch == '\'' || ch == '-') { if (k < BUFFER - 1) // 新增判断 { wordbuffer[k] = ch; ++k; NextWord_flag = true; if (ch == '\'' || ch == '-') interwordpunct = true; } }清理内存避免泄漏
程序结束前,要释放所有分配的结构体和字符串:// 在main函数末尾添加 for (int i = 0; i < wordcount; ++i) { delete[] uniquewords[i]->WORD; delete uniquewords[i]; } delete[] uniquewords;
完整修改后的代码
#define _CRT_SECURE_NO_WARNINGS #define _CRTDBG_MAP_ALLOC #include <iostream> #include <iomanip> #include <fstream> #include <limits> #include <cctype> #include <cstring> 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; struct Word_Count_STRUCT { char* WORD = nullptr; int COUNT = 0; }; int main() { _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); ifstream iphrase; ofstream o_count; 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; 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.get(ch)) { if (isalpha(ch) || ch == '\'' || ch == '-') { if (k < BUFFER - 1) { 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] = new Word_Count_STRUCT(); temp[wordcount]->WORD = cword; temp[wordcount]->COUNT++; uniquewords = temp; ++wordcount; NextWord_flag = false; } interwordpunct = false; NewWord_flag = true; } } } // 内存清理 for (int i = 0; i < wordcount; ++i) { delete[] uniquewords[i]->WORD; delete uniquewords[i]; } delete[] uniquewords; return 0; }
内容的提问来源于stack exchange,提问作者RadLarry12
相关产品推荐
相关产品推荐

