You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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指针,这样能彻底避免内存管理的问题,代码也会简洁很多。比如:
    #include <vector>
    #include <algorithm>
    // ...
    vector<string> lexicon = {"maybe", "this", "works"};
    // 添加单词
    lexicon.push_back(word);
    // 排序
    sort(lexicon.begin(), lexicon.end());
    
    这样完全不需要手动new/delete,安全性和可读性都更高。

内容的提问来源于stack exchange,提问作者Tal J

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:36:30