C++ deleteAlternateNodes用delete报错free正常的原因及二者区别
问题原因分析
运行时错误的核心触发点是Node类的析构函数设计和delete的执行逻辑冲突:
Node类的析构函数内置了if(next) { delete next; }逻辑,调用delete p释放节点时,除了释放p本身占用的内存,还会自动调用p的析构函数,递归释放p指向节点后面挂载的所有后续节点。- 在
deleteAlternateNodes的执行逻辑中,完成q->next = p->next的指针重定向后,直接调用delete p会触发连锁释放,导致q->next指向的后续节点全部被提前释放,后续循环访问p = q->next时操作的是野指针,直接触发运行时错误。 - 替换为
free(p)后能正常运行的原因是free()仅负责释放目标内存块,不会调用Node类的析构函数,也就不会触发后续节点的连锁释放。但这种new分配内存、free释放的用法属于未定义行为,只是碰巧适配当前运行环境,本质存在安全隐患。
如果要改用delete实现正确的释放逻辑,只需要在释放p前将p的next指针置空,阻断析构的连锁释放即可:
q->next = p->next; p->next = NULL; // 新增该行,避免析构函数释放后续节点 delete p; p = q->next;
free()和delete的核心区别 - 归属不同:
free()是C标准库提供的库函数,使用时需要引入对应头文件;delete是C++内置关键字,不需要额外引入依赖。 - 执行逻辑不同:
free()仅完成内存释放操作,不会处理对象的资源清理工作;delete会先调用指向对象的析构函数,完成对象内部的资源清理后,再释放对象占用的内存。 - 配对规则不同:
free()必须和malloc()/calloc()/realloc()等C风格内存分配函数配对使用;delete必须和new关键字配对使用,混用两者属于未定义行为,可能引发内存泄漏、程序崩溃等问题。 - 数组处理差异:释放数组内存时,
delete需要使用专用的delete[]语法;free()不需要区分单个元素和数组的释放逻辑。
内容的提问来源于stack exchange,提问作者Abhinav 1036
相关产品推荐
相关产品推荐

