C++指针动态内存分配:delete后p2仍输出99的原因探究
C++悬垂指针问题解答
首先贴出你提供的两段代码:
原代码
#include <iostream> using namespace std; int * p1, * p2; // Global int pointers void allocate() { p1 = new int(88); // Allocate memory, initial content unknown p2 = new int(99); // Allocate and initialize } int main() { allocate(); cout << *p1 << endl; // 88 cout << *p2 << endl; // 99 delete p1; delete p2; cout << *p1 << endl; cout << *p2 << endl; return 0; } // 输出 // p1 88 // p2 99 // after delete // p1 17962984 // p2 99
修改后的allocate函数
void allocate() { p1 = new int; *p1 = 88; p2 = new int(99); }
为什么delete p2后读取*p2仍得到99?
这是未定义行为导致的偶然结果:
- 执行
delete p2时,只是把p2指向的内存归还给操作系统,操作系统不会立刻清空这块内存,只是标记它为“可以被重新使用”。 - 在这块内存被其他操作覆盖之前,原来的99可能还留在原地,所以你读取
*p2时刚好拿到旧值。但这个结果完全不可靠——换编译器、换运行环境,甚至同一程序多跑几次,结果都可能变,严重时会直接导致程序崩溃。 - 划重点:
delete之后,p2就成了悬垂指针(指向已释放内存的指针),C++标准明确规定访问悬垂指针指向的内存属于未定义行为,绝对不能依赖这种巧合写代码。
两段allocate代码的等价性说明
你修改后的allocate函数和原函数效果完全一致:
- 原写法
p1 = new int(88)是分配内存的同时直接初始化值为88; - 修改后的
p1 = new int; *p1 = 88是先分配未初始化的内存,再手动赋值88。两种方式最终都能让p1指向的内存存储88,所以运行结果没有区别。
适合新手的C++学习参考资料
- 《C++ Primer》:经典入门教材,对指针、内存管理等基础概念讲解得细致全面,适合从零开始系统学习。
- cppreference中文文档:可以查阅C++语法和标准库的权威说明,尤其是内存管理、指针相关章节,能帮你准确理解规则。
- 《Effective C++》:当你有一定基础后,这本书能教你很多避免常见陷阱(比如悬垂指针、内存泄漏)的实用技巧,提升代码质量。
内容的提问来源于stack exchange,提问作者Coder
相关产品推荐
相关产品推荐

