9

下面的代码有什么作用?

obj *x = new obj[100];
delete x; // Note the omission of []

它是否只删除数组中的第一个元素?

4

3 回答 3

11

上面的代码表现出未定义的行为:它应该是

delete[] x;

因为分配是用new[].

当您使用正确的运算符时,指针指向的整个数组将被删除:

obj *x = new obj[100];
delete[] x; // The entire array gets deleted
于 2012-10-08T10:14:44.703 回答
9

即使它是未定义的行为,您也应该注意最可能的结果(为了调试此类问题)。

当您通过 创建数组时new Object[100],首先分配内存。默认行为(假设没有覆盖默认分配器)是简单地调用malloc(100 * sizeof(Object)). 之后,Object需要在每个Object大小的区域上调用 for 的构造函数。这是一个重要的细节:内存被分配一次,但构造函数在 100 个位置被调用。

当一个块通过 分配时malloc,它不能被分段释放。只有调用free(block)才会释放该内存。如果关键字调用,则C++ 关键字在delete内部调用. 因此,删除数组的正确方法是调用. 那么,如果你打电话会发生什么?可能的答案是内存将被释放(全部释放,而不仅仅是第一个元素),但只会调用一个析构函数:第一个元素的析构函数。freenewmallocdelete [] arraydelete array

显然,有很多事实需要考虑。newanddelete不一定与mallocand绑定free。他们可能使用特定架构或操作系统特有的系统调用。(特别是 Windows,在其 C API之外malloc和内部都有一整套堆管理功能。)我只是用and演示了这个示例,因为这是我在单步执行代码时最常看到的。例如,Visual Studio 允许您进入调用并实际查看函数代码。(这是另一个重要的细节。只是简单的函数调用,在很多情况下你甚至可以覆盖它。)freemallocfreenewnewnewdelete


你可以用这个小程序演示这个概念。只需创建一个Object在构造函数期间输出某些内容并在析构函数期间输出其他内容的类。

int main(int argc, char** argv)
{
    Object* o = new Object[4];
    delete o;
    return 0;
}

我运行它,果然:构造函数被调用了 4 次,而析构函数被调用了一次。

于 2012-10-08T16:04:04.640 回答
-1

此代码在 GCC 上表现出明确的行为,即删除第一个对象。

#include <iostream>
#include <stdlib.h>
#include <time.h>

class myclass {

public:

int i;

myclass(){

std::cout <<"myclass constructed \n";

this->i = rand() % 100;

std::cout<<this->i;
}

~myclass(){

std::cout <<"myclass destroyed\n";

std::cout<<this->i;
}       
};

int main()
{

myclass * pt;

srand ( time(NULL) );   

pt = new myclass[3];

delete pt;

return 0;
}
于 2012-10-08T14:25:34.957 回答