我可以对单个元素数组分配使用“operator delete[]”吗

Can I use `operator delete[]` for a single element array allocation?

本文关键字:delete operator 单个 元素 数组 分配 我可以      更新时间:2023-10-16

如果我们将大小为1的对象分配为以下

int *arr = new int[1];

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

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

用户案例:

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

注意

你能让我回到标准来支持你的答案吗?

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

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

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

在第一种可选方案(删除对象)中,delete的操作数的值可以是空指针值、指向由以前的新表达式创建的非数组对象的指针,或者指向表示此类对象基类的子对象(1.8)的指针(第10条)。如果不是,则行为未定义。

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

规则很简单:

  1. 始终平衡newdelete
  2. 始终平衡new[]delete[]

否则会得到未定义的行为

没有异常;即使是new[1]也必须与delete[]平衡并且由于编译器仍然可以保留存储而必须删除new[0]

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

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

您必须使用delete[]

C++11 5.3.5删除

::opt-delete强制转换表达式

::opt-delete[]强制转换表达式

第一种备选方案适用于非数组对象,第二种备选方案则适用于数组。

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

int *arr = new int[1];

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

内存泄漏

由新表达式创建的对象(具有动态存储的对象持续时间),直到新表达式返回的指针在匹配删除表达式中使用。

所以你应该使用delete[]来释放内存,否则你会得到未定义的行为。

并且(实例),如果编译器足够聪明,可以将int * arr = new int[1]作为int,那么它必须足够聪明,才能将arr上的delete[] arr作为delete arr然而delete无法区分arrint*arr = new int[1]int*arr = new intdelete中的[]将指示它。

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

示例:

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

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

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