我可以使用`operator delete []`进行单个元素数组分配吗?

时间:2013-07-12 07:23:51

标签: c++

如果我们分配一个大小为1的对象

int *arr = new int[1];

我们应该使用operator delete[]还是operator delete删除对象?

我担心的原因是编译器是否足够智能将语句转换为单个元素分配int *arr = new int,这会导致调用operator delete[] UB。

用户案例:

我有一个指针,我最终会以各种方式分配,但最终会想要删除它。所以我想知道,对于单个元素分配,如果我一直使用int *arr = new int[1],我可以始终如一地安全地使用operator delete[]

注意

请您回复标准以支持您的回答?

6 个答案:

答案 0 :(得分:13)

您必须使用delete[]而不是delete。不允许编译器将new int[1]更改为new int

(由于int是一种POD类型,new intnew int[1]很有可能在封面下做同样的事情,但如果是这种情况,那么delete[] on int*上的deleteint*也会做同样的事情。)

ISO / IEC 14882:2011 5.3.5 [expr.delete] / 2:

  

在第一个替代方法(删除对象)中,delete的操作数的值可以是空指针值,指向前一个<创建的非数组对象的指针em> new-expression ,或指向表示此类对象的基类的子对象(1.8)的指针(第10条)。如果不是,则行为未定义。

由于int[1]是一个数组对象,如果您尝试使用delete而不是delete[]删除它,则行为未定义。

答案 1 :(得分:6)

规则很简单:

  1. 始终将newdelete
  2. 进行平衡
  3. 始终将new[]delete[]
  4. 进行平衡

    否则你会得到未定义的行为

    没有例外;偶数new[1]必须与delete[]平衡,并且必须删除new[0],因为编译器仍然可以保留存储空间。

答案 2 :(得分:2)

  

我们应该使用运算符delete[]还是operator delete删除对象?

operator delete[]。您已经分配了int数组,因此没有其他选项可以正确解除分配。使用operator delete将调用未定义的行为。

答案 3 :(得分:2)

您必须使用delete[]

C ++ 11 5.3.5删除

  

:: opt delete cast-expression

     

:: opt delete [] cast-expression

     

第一种方法是非数组对象,第二种方法是数组。

包含一个元素的数组仍然是一个数组。

答案 4 :(得分:1)

int *arr = new int[1];

由于您使用[]进行分配,因此您还需要[]使用delete

  

Memory leaks

     

由新表达式创建的对象(具有动态存储的对象)   duration)持续到新表达式返回的指针为止   用于匹配 delete-expression。

因此,您应该使用delete[]来释放内存,否则就会出现未定义的行为。

(incase),如果编译器足够聪明,可以int * arr = new int[1]作为int,那么它必须足够聪明,可以delete[] arr arr 1}}为delete arrdelete无法区分arrint*arr = new int[1]int*arr = new int之间的区别。 [] in delete将表明它。

答案 5 :(得分:0)

不,它不安全,可能会导致一些不必要的情况。
例如,在内存中可以在指针指向的位置旁边放置一些数据(int/char/float ...)。那时如果您使用 delete [] ,那么它可能会尝试删除该数据(如果它是整数),对于其他数据类型,它会导致意外错误。

示例:

int *ptr = new int;
int a = 20;
char c = 'e';
*ptr = 10;
delete [] ptr;

ca变量有可能存储在指针ptr指向的位置旁边,如果a存储在其旁边,则它还会删除“a”,如果存在其他数据类型,则会导致意外的运行时结果。

因此建议仅使用delete[]删除使用新数据类型[]分配的内存。希望这很有用。