c++ - "delete"与堆栈对象的行为是什么?

标签 c++ memory memory-management stack

<分区>

int main()
{
    Class_Name t;
    Class_Name * p = &t;

    delete p;
    return 0;
}  

这段代码在调用 2 个析构函数的情况下执行得很好吗? delete 如何处理堆栈对象?行为是否未定义?

最佳答案

您遇到了未定义的行为。

标准 (N3690) 5.3.5[expr.delete]/2

If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the remainder of this section. In the first alternative (delete object), the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression, or a pointer to a subobject (1.8) representing a base class of such an object (Clause 10). If not, the behavior is undefined.
...

您没有空指针,也没有之前用 new 分配的对象,因此行为未定义。

注意:即使在尝试做

int main()
{
    Class_Name t;
    t.~Class_Name()
    return 0;
}

这将是未定义的行为。即使它没有删除,只是因为它显式调用了具有自动存储持续时间的对象的析构函数。这意味着析构函数将被调用两次,一次是在显式调用它时,第二次是在离开它的作用域时。

标准 12.4[class.dtor]/15

Once a destructor is invoked for an object, the object no longer exists; the behavior is undefined if the destructor is invoked for an object whose lifetime has ended (3.8). [ Example: if the destructor for an automatic object is explicitly invoked, and the block is subsequently left in a manner that would ordinarily invoke implicit destruction of the object, the behavior is undefined. —end example ]

大多数时候尝试做任何类似的事情都会(希望)导致崩溃。使用简单的解构函数,您可能会(倒霉)运气,但什么也不会发生。

这里的术语有点挑剔:C++ 标准不讨论堆栈对象与堆对象,它总是分别讨论自动存储持续时间与动态存储持续时间。正如您在上面的引述中也看到的那样。


您应该始终遵循一般准则:

  • 对于堆栈分配的对象,不要进行任何显式释放/删除(自动调用析构函数)。
  • 对于每一个new应该有一个对应的delete
  • 对于每个 new[] 应该有一个对应的 delete[]
  • 对于每个 malloccalloc 应该有一个相应的 free

关于c++ - "delete"与堆栈对象的行为是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21547180/

相关文章:

strncpy 的 C++ 等价物

c# - 在 ASP.NET MVC 中为 View 初始化模型的不同方法

c++ - g++ 可变大小数组没有警告?

python - 动态数组和删除运算符的 boost::python 内存错误

python - 加载python应用程序时Ubuntu服务器内存不足

c++ - 如何获得真正的 16 位值?

C++ : declaring in if/else : var not declared in this scope

c++ - 更新 glibc 后 std::tan() 非常慢

c++ - 如何编辑随机内存?

C++ 和虚拟析构函数