首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >阵列中的C++ delete[]与delete

问阵列中的C++ delete[]与delete
EN

Stack Overflow用户
提问于 2015-01-07 02:18:32
回答 3查看 1.7K关注 0票数 2

我知道如果我使用new[],我必须使用delete[],但这是我的疑问:

声明:

代码语言:javascript
复制
char **data; // This will be a bi-dimensional array

构造:

代码语言:javascript
复制
data = new char*[10];
for (int i=0; i<10; ++i) 
{
  data[i] = new char[128];
}

销毁:

代码语言:javascript
复制
for (int i=0; i<10; ++i) 
{
  delete data[i]; // <--- delete or delete[] ???
}
delete[] data;

另一种情况是我有一个对象数组:

声明:

代码语言:javascript
复制
myClass **object;

构造:

代码语言:javascript
复制
object = new myClass*[10];
for (int i=0; i<10; ++i) 
{
  object[i] = new myClass();
}

销毁:

代码语言:javascript
复制
for (int i=0; i<10; ++i) 
{
  delete object[i]; // <--- this object[] is not an array, right?
}
delete[] object; // <--- Is this correct?
EN

回答 3

Stack Overflow用户

发布于 2015-01-07 02:30:44

你基本上回答了你自己的问题。因为data[i]是一个数组,所以你需要delete[]。object[i]是用new分配的,所以你可以delete它。由于对象和数据都是数组,因此需要对它们执行delete[]操作。

票数 4
EN

Stack Overflow用户

发布于 2015-01-07 02:33:19

指针data的第一个维度是一个数组。第二个维度也是一个数组。因此,您必须使用delete[]来正确地释放从new[]中保留的内存。

对于您的对象,第一个维度是使用new分配的。所以你必须使用delete。然后在object上使用delete[],因为它是一个数组。

票数 1
EN

Stack Overflow用户

发布于 2015-01-08 00:03:55

您提到的助记符(delete []表示new [],delete表示new)是一个很好的实践,应该强制执行。

然而,当涉及到基类型(int、char、delete[] *等)和类时,delete和void之间存在巨大的差异。

new和malloc的不同之处在于,一个调用构造函数,而另一个不调用。对于析构函数,delete和free也有同样的关系。

在您的示例中,您给出了两种情况:一种是分配了简单类型的数组,另一种是分配了对象数组。

行为是不同的。

对于简单类型,delete和delete[]将产生相同的结果。

原因?好的,您基本上分配了一个由10个char*指针组成的块,所以删除它是没有问题的(分配的内存分页将被释放)。

换句话说,如果你有

代码语言:javascript
复制
 char* a = new char[100];

然后

代码语言:javascript
复制
 delete a;

和

代码语言:javascript
复制
 delete[] a;

将产生相同的结果(请注意,您使用了新的[]);

当涉及到具有构造函数和析构函数的对象时,这种行为是不同的。

让我们以下面的类为例:

代码语言:javascript
复制
class SimpleClass
{
   public:
         SimpleClass(){printf("constructed");
         ~SimpleClass()(printf("destructed");
}

和以下代码:

代码语言:javascript
复制
SimpleClass* arr1 = new SimpleClass[5];
SimpleClass* arr2 = new SimpleClass[5];
char* arr3 = new char[5];
char* arr4 = new char[5];

delete[] arr4;
delete arr3;
delete[] arr2;
delete arr1; //notice the surprise ?

在Visual Studio中运行上面的代码(如果可以)并打开一个内存查看器。您将看到,在ptrs arr4和arr3上分配的内存已正确失效,arr2也是如此。

但是,当尝试在不使用[]调用的情况下删除arr1时,您将得到一个SigSev错误。

为什么?

因为在arr2的情况下,您有一个已分配对象的数组,而delete[]语句意味着“传递数组中的每个析构函数”。

在arr1的情况下,它意味着:调用在指针arr1处分配的对象的析构函数...如果考虑到在该地址上分配了超过1个对象,并且最终尝试释放小于初始分配大小的页,则有点不幸。

底线:

new[]的delete[]和新的delete!

每次都有效!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27804671

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档