在C++中删除vs delete []运算符

shr*_*sva 115 c++ memory-management delete-operator

C++中deletedelete[]运算符有什么区别?

Nic*_*yer 131

delete运营商释放内存,并呼吁与创建一个对象析构函数new.

delete []操作者解除分配存储器以及用于与创建的对象的阵列调用析构new [].

使用delete由返回一个指针new []delete []通过返回的指针new导致不确定的行为.

  • 如果标准没有定义完成后会发生什么,那么即使您的编译器确定性地执行了您希望它执行的操作,它仍然是"未定义的行为".另一个编译器可能会完全不同. (16认同)
  • 我想知道是否在像int或char这样的原始类型的new []数组上使用delete也必然导致未定义的行为。使用基本类型时,似乎数组大小没有存储在任何地方。 (2认同)

Joh*_*itb 80

delete[]操作是用来删除阵列.的delete操作者用于删除非阵列对象.它分别调用operator delete[]operator delete函数删除数组或非数组对象在(最终)调用数组元素或非数组对象的析构函数后占用的内存.

以下是关系:

typedef int array_type[1];

// create and destroy a int[1]
array_type *a = new array_type;
delete [] a;

// create and destroy an int
int *b = new int;
delete b;

// create and destroy an int[1]
int *c = new int[1];
delete[] c;

// create and destroy an int[1][2]
int (*d)[2] = new int[1][2];
delete [] d;
Run Code Online (Sandbox Code Playgroud)

对于new创建数组(因此,new type[]new应用于数组类型构造),标准operator new[]在数组的元素类型类或全局范围中查找a ,并传递所请求的内存量.它可能会请求比N * sizeof(ElementType)它想要的更多(例如存储元素的数量,因此稍后在删除时知道要完成多少个析构函数调用).如果类声明了operator new[]内存量接受另一个的附加size_t,那么第二个参数将接收分配的元素数 - 它可以将它用于它想要的任何目的(调试等等).

对于new创建非数组对象的a,它将operator new在元素的类或全局范围中查找a .它传递了所请求的内存量(完全sizeof(T)一直).

对于a delete[],它查看数组的元素类类型并调用它们的析构函数.使用的operator delete[]函数是元素类型的类中的函数,或者如果在全局范围中没有函数.

对于a delete,如果传递的指针是实际对象类型的基类,则基类必须具有虚拟析构函数(否则,行为未定义).如果它不是基类,则调用该类的析构函数,并使用operator delete该类或全局operator delete中的a.如果传递了基类,则调用实际对象类型的析构函数,并operator delete使用该类中找到的析构函数,如果没有,operator delete则调用全局.如果operator delete类中有第二个类型参数size_t,它将接收要解除分配的元素数.


小智 14

这是c ++ malloc/free,new/delete,new []/delete []中allocate/DE-allocate模式的基本用法

我们需要相应地使用它们.但我想对删除和删除[]之间的区别添加这种特殊的理解

1)delete用于解除为单个对象分配的内存

2)delete []用于解除为对象数组分配的内存

ABC类{}

ABC*ptr =新ABC [100]

当我们说new [100] ..编译器可以获得有关需要分配多少对象的信息(这里是100)并将为每个创建的对象调用构造函数

但相应地,如果我们在这种情况下只使用delete ptr,编译器将不知道ptr指向的对象数量,并且最终将调用析构函数并仅删除1个对象的内存(保留析构函数的调用和剩余99个对象的释放) ).因此会有内存泄漏

所以我们需要在这种情况下使用delete [] ptr.

  • 这应该是正确的答案.没有其他答案提到明显的区别:"但相应地,如果我们只是在这种情况下使用delete ptr,编译器将不知道ptr指向的对象有多少,并且最终将调用析构函数并仅删除1个对象的内存" (2认同)

Eka*_*vya 9

当我问这个问题时,我真正的问题是,“两者之间有区别吗?运行时是否必须保留有关数组大小的信息,因此它是否无法分辨我们指的是哪一个?” 这个问题没有出现在“相关问题”中,所以为了帮助像我这样的人,这里是答案:“为什么我们甚至需要删除[]运算符?”

  • 感谢您回来并把这个放进去。 (2认同)

san*_*983 6

运算符deleteanddelete []分别用于销毁用newand创建的对象new[],返回分配给编译器内存管理器可用的内存。

new来创建的对象必须用 来销毁delete,用new[]来创建的数组应该用 来删除delete[]