为何使用delete[]释放动态数组后仍可访问其值?
为什么delete[]释放数组内存后仍能访问其中的值?
这是C++里典型的悬空指针引发的未定义行为,本质是你对delete[]的作用理解有一点偏差,下面给你拆解清楚:
1. delete[]到底做了什么?
当你调用delete[] arr时,它只做两件核心事:
- 通知操作系统:这块动态分配的内存已经不再被当前程序占用,可以回收,后续分配内存时可以把这块区域分给其他需求。
- 对于数组里的对象(如果是自定义类型),会调用每个元素的析构函数(你的代码里是int类型,没有析构函数,所以这步跳过)。
它不会做的事:
- 不会清空这块内存里存储的数据,原来的数值可能还留在原地。
- 不会把指针
arr置为nullptr,arr仍然指向原来的内存地址。
2. 为什么还能读到旧值?
在操作系统还没把这块内存分配给其他进程,或者你的程序还没用到这块内存区域之前,原来的数据并没有被覆盖,所以你通过arr[i]去读的时候,还能拿到之前存的数值。但这完全是巧合,属于“运气好”的情况——一旦操作系统把这块内存分给其他程序,或者你的后续代码覆盖了这块区域,再去读就会得到随机乱码,甚至直接导致程序崩溃。
3. 这种行为的风险
这种访问已释放内存的操作,属于C++标准里的未定义行为。标准没有规定程序此时必须崩溃或者必须输出错误值,不同编译器(比如GCC、MSVC)、不同操作系统(Windows、Linux)、甚至同一程序的不同运行次数,结果都可能不一样。你绝对不能依赖这种行为写代码,这是严重的bug隐患。
4. 正确的处理方式
在delete[]之后,最好立刻把指针置为空指针,避免后续误访问:
delete[] arr; arr = nullptr; // 置空指针
这样如果后续不小心再访问arr,程序会触发空指针错误(比如崩溃或者抛出异常),能帮你快速定位问题,而不是出现难以排查的随机错误。
结合你的代码来看,delete[] arr之后的循环访问就是在踩已经不属于你的内存,这次能输出原来的数值只是偶然情况,千万不要觉得这是正常现象。
内容的提问来源于stack exchange,提问作者Abhishek jha
相关产品推荐
相关产品推荐

