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

自定义C++ String类报错:待释放指针未分配,求解决方案

解决自定义String类的内存释放错误

首先,你遇到的malloc错误本质是野指针被非法释放。让我们一步步拆解问题和解决方案:

错误根源

当你调用默认构造函数String s1;时,构造函数会调用initialize(),但此时charArr作为类的非静态成员变量,在C++98/03中没有显式初始化的话,会持有随机垃圾值(不是你以为的0或nullptr)。这就导致if(charArr != 0)的条件意外成立,代码尝试delete[]一个从未被new分配过的野指针,触发了内存错误。

另外,析构函数调用initialize()也是不合理的——initialize()是用来重置对象状态的,析构函数只需要完成自身资源的清理即可。

分步解决方案

1. 用构造函数初始化列表避免野指针

因为你不能使用C++11的类内初始化特性,我们可以在每个构造函数的初始化列表里显式初始化len和charArr,确保对象创建时成员变量处于安全状态:

// String.cpp 中修改构造函数:
String::String() : len(0), charArr(nullptr) {
    // 初始化列表已经完成了基础初始化,无需调用initialize()
}

String::String(const char *arr) : len(0), charArr(nullptr) {
    copyString(arr);
}

String::String(const String& arr) : len(0), charArr(nullptr) {
    copyString(arr.charArr);
}

2. 修正initialize()的职责与逻辑

initialize()的定位应该是重置对象的现有状态(比如清空已有的字符串),而不是初始化新对象。我们要确保只在charArr确实指向已分配内存时才释放:

void String::initialize(){
    if(charArr != nullptr){
        delete [] charArr;
        charArr = nullptr; // 释放后置空,避免悬空指针
    }
    len = 0;
}

3. 修复析构函数的错误调用

析构函数只需要负责清理当前对象的资源,不需要调用initialize(),直接释放charArr即可:

String::~String(){
    delete [] charArr;
    charArr = nullptr; // 可选,但这是避免悬空指针的好习惯
}

4. 完善copyString()的安全性

现在charArr已经在构造时初始化为nullptr,copyString()里的判断逻辑会更安全,同时我们可以补充字符串结尾的\0保证(strncpy不会自动添加):

void String::copyString(const char *arr){
    if(arr == nullptr){
        initialize();
        return;
    }
    size_t tempLen = strnlen(arr, MAX_LEN);
    len = tempLen; // strnlen返回的长度不会超过MAX_LEN,无需额外判断
    initialize(); // 先释放原有内存(如果存在)
    charArr = new char[len + 1]();
    strncpy(charArr, arr, len);
    charArr[len] = '\0'; // 确保字符串以终止符结尾
}

验证修改后的代码

现在运行你的main()函数,就不会再出现内存错误了。所有构造函数都保证了charArr初始为nullptr,避免了野指针的问题,资源的分配和释放逻辑也更清晰严谨。

内容的提问来源于stack exchange,提问作者loay mansour

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:52:05