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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 05:09:57