C++中动态对象释放/解引用后仍可被引用的原因?
为啥C++里动态对象被释放后还能被引用(甚至读到正确值)?
这其实是C++里一个非常典型的「未定义行为」坑,咱们结合你的代码一步步说清楚:
核心原因:内存释放后不会立刻被清空或回收
当你调用delete this(或者delete ptr)的时候,操作系统只是把这块内存标记为「可用」,等待后续分配给其他程序/变量使用,但不会立刻把内存里的数据擦除。
在你的代码里:
- 先通过
new Marie创建对象,随后在ShowMarie()里把x赋值为5; - 调用
delete this触发析构函数,但你的析构函数只是打印字符串,没有修改x的值; - 此时
ptr变成了悬空指针(指向已经被释放的内存),但这块内存里的x=5还没被覆盖; - 当你访问
ptr->x时,只是刚好读到了内存里残留的旧值而已。
重点:这是绝对的未定义行为!
别被这次输出5的结果迷惑了——这种行为完全不可靠:
- 下次运行程序,可能输出随机垃圾值,甚至直接崩溃;
- 如果在这段代码之后有其他内存分配操作,这块内存可能被复用,
ptr->x就会变成其他变量的值; - 不同编译器、不同编译模式(Debug/Release)的表现都不一样:比如Debug模式下,很多编译器会把释放后的内存填充成
0xCCCCCCCC这类标记值,此时你访问ptr->x就会看到奇怪的数字,而Release模式通常不会做这种填充,更容易让你误以为代码没问题。
怎么避免这种问题?
- 手动管理内存时,
delete指针后立刻把它置为nullptr,这样后续访问时能快速发现问题(比如触发空指针错误,而不是偷偷读到错误值); - 优先使用C++的智能指针(
std::unique_ptr、std::shared_ptr),它们会自动管理内存生命周期,从根源上避免悬空指针。
内容的提问来源于stack exchange,提问作者tusharRawat
相关产品推荐
相关产品推荐

