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

C++中使用new/delete操作结构体节点时程序偶发崩溃问题排查

程序崩溃的根本原因及修复方案

1. 字符串内存分配不足导致堆破坏

在itemNode和customerNode的构造函数中,你为字符串分配内存时仅使用了strlen(name)的长度,但C风格字符串需要额外1字节来存储末尾的\0结束符。strcpy会将源字符串的\0也拷贝过去,这直接造成堆内存越界写入,破坏了堆的内部结构。这类问题的表现具有随机性——当越界未覆盖关键数据时程序可能正常运行,一旦覆盖堆的管理信息就会触发崩溃。

修复方法:分配内存时额外预留1字节用于存储结束符:

// itemNode构造函数修改
this->itemName = new char[strlen(name) + 1];
// customerNode构造函数修改
this->fullName = new char[strlen(name) + 1];

2. 潜在的重复内存释放风险

虽然你在main函数中手动删除basket后将其设为nullptr,但如果后续代码逻辑变动(比如遗漏了置空操作),customerNode的析构函数会再次删除已经被释放的basket指针,触发二次内存释放,这也是程序崩溃的常见诱因。另外你当前的手动删除操作其实是多余的——customerNode的析构函数已经会递归删除整个商品链表,完全不需要提前手动处理。

简化后的main函数写法:

int main()
{
    customerNode *customer1 = new customerNode(14235, "Georges Politzer", nullptr, nullptr);

    itemNode *item3 = new itemNode(5355, "Pen", 2, nullptr);
    itemNode *item2 = new itemNode(1351, "Folder Case", 1, item3);
    itemNode *item1 = new itemNode(4412, "Paper Clips", 20, item2);

    customer1->basket = item1;

    // 无需手动删除basket,customer析构函数会自动递归清理整个商品链表
    delete customer1;

    return 0;
}

额外优化建议

尽量避免使用裸指针和手动内存管理,C++中推荐用std::string替代C风格字符串,用std::unique_ptr/std::shared_ptr管理动态内存,从根源上规避内存错误。例如将char* itemName改为std::string itemName,就完全不需要手动分配/释放内存,也不会出现字符串越界问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 07:45:48