You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

程序编译正常但运行时出现*** glibc detected *** free(): invalid pointer错误求助

分析与修复:free(): invalid pointer 错误

你的问题出在构造函数中未初始化eMessage指针就调用了message()函数,导致clear()尝试释放一个未初始化的垃圾指针,触发了glibc的内存错误。

问题细节

看你的构造函数实现:

ErrorState::ErrorState(const char* errorMessage) {
    if (errorMessage == nullptr) {
        eMessage = nullptr;
    } else {
        message(errorMessage); // 直接调用message,此时eMessage未初始化
    }
}

errorMessage不为nullptr时,你直接调用message(),而message()的第一行就是clear()。这时候eMessage还没有被赋值,是一个随机的垃圾值,大概率不是nullptr,所以clear()会执行delete[] eMessage;——这相当于尝试释放一块不属于你的内存,自然会触发free(): invalid pointer错误。

修复方案

只需要在构造函数的最开始,先把eMessage初始化为nullptr,确保后续clear()调用时不会操作无效指针:

ErrorState::ErrorState(const char* errorMessage) : eMessage(nullptr) { // 用初始化列表赋值为nullptr
    if (errorMessage != nullptr) {
        message(errorMessage);
    }
}

或者在构造函数体内先初始化:

ErrorState::ErrorState(const char* errorMessage) {
    eMessage = nullptr; // 先初始化指针
    if (errorMessage != nullptr) {
        message(errorMessage);
    }
}

额外优化建议

  • 尽量使用成员初始化列表来初始化类成员,这是更规范的C++写法,也能从根源避免这类未初始化的问题。
  • message()函数增加空指针判断,避免传入nullptr时调用strlen()导致崩溃:
    void ErrorState::message(const char* str) {
        if (str == nullptr) {
            clear();
            return;
        }
        int strLen = strlen(str);
        clear();
        eMessage = new char[strLen + 1];
        strcpy(eMessage, str);
    }
    
  • ostream& operator<<的参数改成const ErrorState&,这样可以支持临时对象的输出(比如cout << ErrorState("test");),同时符合const正确性:
    std::ostream& operator<<(std::ostream& os, const ErrorState& errState) {
        if (!errState.isClear()) os << errState.message();
        return os;
    }
    

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

火山引擎 最新活动