C++动态扩展指针数组构建字典时出现访问违例求助
问题分析与修复方案
首先,你遇到的0xC0000005访问违例,核心是代码里的三个关键错误,我逐一给你拆解:
1. 指针参数未使用引用传递
你的newStr函数第一个参数是char** lexicon,这是值传递——函数内部的lexicon只是外部指针的副本。当你在函数里执行lexicon = updated时,修改的只是副本,main函数里的原始lexicon指针根本没被更新。而你又在函数里delete了原始的lexicon内存,之后main里再访问这个指针,就会触发野指针访问错误。
修复方法:把参数改成指针的引用,让函数能直接修改外部的指针:
void newStr(char**& lexicon, int& lexiconSize, char word[])
2. 错误释放了新分配的内存
函数最后这段代码完全是画蛇添足:
// deallocate the memory created for the updated lexicon for (int i = 0; i < lexiconSize; i++) { delete[] updated[i]; } delete[] updated;
你刚把lexicon指向updated,转头就把updated的内存释放了,这会导致lexicon变成悬空指针,后续任何对它的操作都会触发内存访问错误。这段代码必须删掉。
3. 冒泡排序逻辑有误
当前的排序循环写法有问题,两层循环都从1开始,而且没有设置正确的终止条件,会导致重复比较、排序不彻底。正确的冒泡排序应该是外层循环控制排序轮数,内层循环控制每轮的比较范围:
if (lexiconSize > 1) { for (int i = 0; i < lexiconSize - 1; i++) { for (int j = 0; j < lexiconSize - 1 - i; j++) { if (strcmp(lexicon[j], lexicon[j + 1]) > 0) { char t[MAX]; strcpy_s(t, MAX, lexicon[j]); strcpy_s(lexicon[j], MAX, lexicon[j + 1]); strcpy_s(lexicon[j + 1], MAX, t); } } } }
修正后的完整代码
#define MAX 80 #include <iostream> #include <cstring> using namespace std; void newStr(char**& lexicon, int& lexiconSize, char word[]) { // 创建新的扩容后的字典 char** updated = new char*[++lexiconSize]; // 复制旧字典的内容并添加新单词 for (int i = 0; i < lexiconSize; i++) { updated[i] = new char[MAX]; if (i < lexiconSize - 1) { strcpy_s(updated[i], MAX, lexicon[i]); } else { strcpy_s(updated[i], MAX, word); } } // 释放旧字典的内存 for (int i = 0; i < lexiconSize - 1; i++) { delete[] lexicon[i]; } delete[] lexicon; // 更新指针到新字典 lexicon = updated; // 按字母序排序 if (lexiconSize > 1) { for (int i = 0; i < lexiconSize - 1; i++) { for (int j = 0; j < lexiconSize - 1 - i; j++) { if (strcmp(lexicon[j], lexicon[j + 1]) > 0) { char t[MAX]; strcpy_s(t, MAX, lexicon[j]); strcpy_s(lexicon[j], MAX, lexicon[j + 1]); strcpy_s(lexicon[j + 1], MAX, t); } } } } } int main() { int lexiconSize = 3; char** lexicon; char word[MAX] = {}; // 初始化测试字典 lexicon = new char*[lexiconSize]; lexicon[0] = new char[MAX]; strcpy_s(lexicon[0], MAX, "maybe"); lexicon[1] = new char[MAX]; strcpy_s(lexicon[1], MAX, "this"); lexicon[2] = new char[MAX]; strcpy_s(lexicon[2], MAX, "works"); cout << "enter the word to add" << endl; cin >> word; newStr(lexicon, lexiconSize, word); // 打印测试,验证排序结果 cout << "Updated lexicon:" << endl; for (int i = 0; i < lexiconSize; i++) { cout << lexicon[i] << endl; } // 程序结束时释放字典内存 for (int i = 0; i < lexiconSize; i++) { delete[] lexicon[i]; } delete[] lexicon; return 0; }
额外建议
- 可以考虑用C++标准库的
std::vector<std::string>来替代手动管理的二维char指针,这样能彻底避免内存管理的问题,代码也会简洁很多。比如:
这样完全不需要手动new/delete,安全性和可读性都更高。#include <vector> #include <algorithm> // ... vector<string> lexicon = {"maybe", "this", "works"}; // 添加单词 lexicon.push_back(word); // 排序 sort(lexicon.begin(), lexicon.end());
内容的提问来源于stack exchange,提问作者Tal J
相关产品推荐
相关产品推荐

