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
相关产品推荐
相关产品推荐

