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

Milestone2.exe出现std::bad_alloc未处理异常,请求排查ErrorState类代码问题

排查std::bad_alloc异常的原因

首先,std::bad_alloc异常通常在内存分配请求无法被系统满足时抛出,结合你的ErrorState类代码,主要有以下几个明确的诱因:

1. 传入message()的字符串为nullptr引发未定义行为

你的message()函数直接调用strlen(str)计算字符串长度,但如果调用方传入的str是nullptr,strlen(nullptr)属于未定义行为——它可能返回一个极大的随机数值,随后new char[strlen(str)+1]会尝试分配远超系统可用内存的空间,直接触发std::bad_alloc。

看这段有问题的实现:

void ErrorState::message(const char* str) {
    this->m_message = new char[strlen(str) + 1];
    strcpy(this->m_message, str);
}

这里完全没有检查str是否有效,一旦传入空指针就会触发上述问题。

2. 未释放原有内存导致内存泄漏,最终耗尽系统内存

每次调用message()时,你直接为m_message分配新内存,但没有释放之前已经指向的内存块。这会导致内存泄漏:每调用一次message(),就有一块内存无法被回收,随着程序运行,系统可用内存逐渐被耗尽,最终在某次new操作时抛出std::bad_alloc。

举个例子,像这样的调用就会泄漏内存:

ErrorState err;
err.message("First error");
err.message("Second error"); // "First error"对应的内存块永远无法被释放

3. 潜在风险:默认拷贝构造/赋值的浅拷贝问题

虽然你注释掉了自定义的拷贝构造和赋值运算符,但C++会自动生成默认版本。默认拷贝构造会执行浅拷贝,也就是两个ErrorState对象的m_message指向同一块内存。当其中一个对象被销毁时,内存会被释放,另一个对象的m_message就变成悬空指针;如果后续对这个悬空指针进行操作(比如再次调用message()),可能引发包括内存分配失败在内的各种未定义行为。


快速修复建议

针对上述问题,你可以这样调整代码:

  1. 在message()开头检查输入有效性,并先释放原有内存:
void ErrorState::message(const char* str) {
    if (str == nullptr) {
        clear();
        return;
    }
    // 先释放旧内存,避免泄漏
    clear();
    this->m_message = new char[strlen(str) + 1];
    strcpy(this->m_message, str);
}
  1. 启用已注释的删除声明,明确禁用拷贝构造和赋值运算符,避免浅拷贝风险:
ErrorState(const ErrorState& em) = delete;
ErrorState& operator=(const ErrorState& em) = delete;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:03:21