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

C++自定义String类运行报pointer being freed was not allocated错误求解

问题排查与修复

核心错误原因

  • 未显式实现拷贝赋值运算符operator=:C++类如果没有自定义拷贝赋值运算符,编译器会自动生成默认的浅拷贝版本。执行string1 = s1这类赋值操作时,只会直接复制str指针的地址,不会重新分配内存拷贝字符串内容,导致两个对象的str成员指向同一块堆内存。两个对象生命周期结束调用析构函数时,同一块内存会被重复释放,触发malloc报错。
  • 补充隐患:默认构造函数中str为NULL,如果直接对默认构造的未赋值对象执行cout输出,会触发未定义行为;另外当前operator<=的实现是比较字符串长度而非字典序,不符合常规字符串比较逻辑,可按需调整。

修复方案

第一步:新增拷贝赋值运算符声明

在String类的public成员中添加operator=的声明:

class String {
    char *str;
    int len;

public:
    String();
    String(const char*);
    String(const String&);
    ~String();
    // 新增拷贝赋值运算符声明
    String& operator=(const String&);
    friend String operator + (const String&, const String&);
    friend bool operator <= (const String&, const String&);
    friend ostream& operator << (ostream&, const String&);
};

第二步:实现深拷贝的赋值运算符

String& String::operator=(const String& str1)
{
    // 防止自赋值
    if(this == &str1)
        return *this;
    // 释放当前对象原有堆内存
    delete[] str;
    // 分配新内存并拷贝内容
    len = str1.len;
    str = new char[len + 1];
    strcpy(str, str1.str);
    return *this;
}

可选优化

如果要规避空对象输出的未定义行为,可以调整默认构造函数,给空字符串分配1字节存储结束符:

String::String(void)
{
    len = 0;
    str = new char[1];
    str[0] = '\0';
}

如果需要operator<=符合常规字符串字典序比较逻辑,修改实现如下:

bool operator <= (const String& str1, const String& str2)
{
    return strcmp(str1.str, str2.str) <= 0;
}

验证

修改完成后重新编译运行,输出结果正常,不会再触发内存报错:

New
York
NewDelhi

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 04:54:03