【问题标题】:Why two operators for deleting dynamically allocated memory? [duplicate]为什么要使用两个运算符来删除动态分配的内存? [复制]
【发布时间】:2015-01-27 14:44:18
【问题描述】:

这个问题可能听起来有点奇怪,但我从来没有完全明白为什么我们需要有两种不同的语法来删除 C++ 中动态分配的内存?

例如,

int *p = new int[10];
delete[] p; // why not just delete p;?

在普通的旧 C 语言中,您只需使用 free 函数来释放为指针分配的内存,而不管分配的元素数量如何。当然,C++ 有点复杂,因为它允许类类型调用它们的析构函数等。但是,我认为在 C++ 中使用单一语法删除动态分配的内存没有任何障碍。

决定使用delete和delete[]这两个版本有什么根本原因吗?

不仅如此,如果您使用 delete 而不是 delete[],大多数编译器甚至不会警告您,这会产生未定义的行为。

【问题讨论】:

  • 您不是在删除指针,而是在指针上使用 delete[] 运算符,这首先是错误的方法

标签: c++ pointers language-lawyer


【解决方案1】:

该语言允许您重载底层的分配和解除分配功能。您可能希望对单个对象和数组执行不同的操作;拥有两个不同的运算符可以让您做到这一点。

【讨论】:

    【解决方案2】:

    带有 delete[] 运算符的表达式,首先调用适当的 数组中每个元素的析构函数(如果它们属于一个类 type),然后调用数组释放函数。

    来自here

    【讨论】:

    • 我知道,我不明白为什么编译器不能以某种方式只使用delete 而不是delete[]
    【解决方案3】:

    根本原因是数组没有析构函数。但是数组仍然是对象。因此,当数组动态分配时,需要特殊处理。指向对象的指针与指向数组第一个元素的指针无法区分,因此您需要一种特殊的语言构造来指示指针指向数组,并且需要调用多个数组元素的析构函数。

    【讨论】:

    • 这是有道理的,感谢您的回答,这就是现在 C++ 代码中正在发生的事情。但是,编译器应该不可能区分这些情况,因为我从来没有看到两者之间的混合。即,是否有任何合理的示例,您可能希望在动态分配的数组上使用普通的delete(对象)在C++?如果不是,那么编译器在 C++ 源文件中跟踪什么是数组和什么不是数组应该不会太难。
    • @vsoftco: void surprise_me(int * p) { delete p; }
    • 很公平,我希望我能够给出 +n 而不是 +1 :) 这是在函数调用中衰减为指针的数组的旧业务,我个人讨厌(尽管我了解保持向后兼容性的功能。
    • @vsoftco:我认为这是误导。真正的问题是动态数组是非常非常奇怪的野兽。您可以分配动态类型的对象,即从不表达式类型的类型,通过说new U[n],并且您永远不会获得指向该对象的指针。您只能获得指向其子对象之一的指针。所以数组到指针的衰减永远不会起作用,因为你甚至看不到数组。
    • 好吧,同意,但是,在某种意义上,malloc 也是如此。你得到一个指向int的指针,但是,当你调用free时,编译器知道你分配了例如512 个整数,然后释放它们。我的问题基本上是为什么不能将其提升为C++,当然还要额外调用析构函数。从用户的角度来看,int 指针与分配给 1 个int 或512 ints 没有什么不同。
    猜你喜欢
    • 1970-01-01
    • 2021-09-05
    • 1970-01-01
    • 2014-01-19
    • 2011-02-16
    • 1970-01-01
    • 2018-01-03
    • 2013-03-02
    • 1970-01-01
    相关资源
    最近更新 更多