指向数组的简单指针

时间:2012-10-08 10:13:01

标签: c++

以下代码有何作用?

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

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

3 个答案:

答案 0 :(得分:11)

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

delete[] x;

因为分配是使用new[]完成的。

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

obj *x = new obj[100];
delete[] x; // The entire array gets deleted

答案 1 :(得分:9)

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

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

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

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


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

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

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

答案 2 :(得分:-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;
}