在C++中两次delete nullptr是否属于不安全的未定义行为?
[...] 无视标准后续就会遇到问题。我见过的一个常见例子是,delete空指针是没问题的,但你不能在没有将指针重置为某个有效指针值的情况下两次delete它。如果两次delete同一个非空指针,大概率会出现段错误;如果是空指针通常看起来能正常运行,但这一表现并没有标准保障。实际上20世纪80年代有一款编译器就不支持这种操作,因为delete指针时会向被删除的指针写入新值。所以再次提醒,请务必遵循标准。
两次delete空指针属于未定义行为的原因
你存在的认知偏差核心是混淆了两种不同的delete场景:
- 直接对空指针常量执行delete操作,比如连续写两次
delete nullptr;,这种操作完全符合C++标准要求,标准明确保证delete空指针不会执行任何操作,不存在未定义行为。 - 演讲中提到的未定义行为,特指对同一个左值指针变量连续执行两次delete、且两次操作之间没有重新给指针赋值的情况,哪怕第一次delete时指针的值是nullptr:
C++标准从未规定delete操作不能修改传入的指针本身的值,第一次delete执行完成后,该指针变量的存储值就处于不确定状态。即使它初始值是nullptr,也可能被delete操作改写为非空的无效值,第二次delete时操作的就是无效指针,自然属于未定义行为。演讲中提到的老式编译器就是该类实现的典型代表。
析构函数是否需要判空的问题
你之前了解的“析构函数中不需要检查指针是否为空”的结论仍然正确。
C++标准明确保障单次delete空指针是完全合法的,不会产生任何副作用,所以不需要在delete前额外做判空处理。
你需要规避的是重复释放同一个指针的风险,正确的解决路径不是在delete前判空,而是:
- 每次执行完delete操作后,立刻手动将指针赋值为
nullptr,避免后续误操作 - 优先使用
std::unique_ptr、std::shared_ptr等标准库智能指针,自动管理内存生命周期,从根源上避免重复释放问题
内容的提问来源于stack exchange,提问作者Kidsunbo
相关产品推荐
相关产品推荐

