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

C++执行delete[] p释放动态数组后值仍存在是什么原因?

核心结论

你遇到的现象不是代码编写逻辑遗漏,是访问已释放内存触发的未定义行为,和VSCode、所用插件的运行环境没有本质关系。


原理说明
  • delete[]的实际作用只有两个:
    1. 对数组内每个元素调用对应析构函数,int是基础内置类型,没有自定义析构逻辑,这一步不会产生任何操作
    2. 将指针指向的堆内存块标记为“空闲可复用”,交还给堆内存管理器
      整个释放过程没有任何规则要求强制擦除内存中存储的旧数据,也不会自动修改原指针本身的指向。
  • 执行delete[] p后,p就成为了悬空指针,此时读写p[0]、p[1]属于C++标准明确规定的未定义行为:标准不对这类操作的结果做任何保证,你可能读到旧值、可能读到随机脏数据、可能程序直接崩溃,任何运行结果都属于“符合标准”的表现,不存在“释放后值一定会改变”的规则。
  • 你当前运行能稳定读到10、20的原值,只是因为程序释放内存后没有立刻对这块内存做新的写入操作,操作系统也没有回收对应的内存页,旧数据暂时残存在内存地址上而已。这个结果完全不稳定:换编译优化等级、增加几行其他内存分配的代码、换不同的编译器/操作系统,运行结果都可能发生变化,绝不能在实际代码中依赖这种表现。
  • 你当前用CodeRunner默认的编译配置通常是无优化的Debug模式,默认内存分配器不会在释放内存时主动擦写内容,所以很容易观察到“释放后还能读旧值”的现象;如果开启地址消毒器(ASAN)这类内存检测工具编译,访问已释放内存会直接抛出明确的内存错误,不会给你读到旧值的机会。

编码建议

释放堆内存后请第一时间将指针置为nullptr,从根源避免意外访问悬空指针的问题。

对应代码片段参考:

delete[] p;
p = nullptr;

置空后如果再误访问p[0],绝大多数运行环境会直接触发内存访问错误崩溃,可以快速定位问题,避免隐蔽的内存bug。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 12:09:20