如果我们分配一个大小为1的对象
int *arr = new int[1];
我们应该使用operator delete[]
还是operator delete
删除对象?
我担心的原因是编译器是否足够智能将语句转换为单个元素分配int *arr = new int
,这会导致调用operator delete[]
UB。
用户案例:
我有一个指针,我最终会以各种方式分配,但最终会想要删除它。所以我想知道,对于单个元素分配,如果我一直使用int *arr = new int[1]
,我可以始终如一地安全地使用operator delete[]
注意
请您回复标准以支持您的回答?
答案 0 :(得分:13)
您必须使用delete[]
而不是delete
。不允许编译器将new int[1]
更改为new int
。
(由于int
是一种POD类型,new int
和new int[1]
很有可能在封面下做同样的事情,但如果是这种情况,那么delete[]
on int*
上的delete
和int*
也会做同样的事情。)
ISO / IEC 14882:2011 5.3.5 [expr.delete] / 2:
在第一个替代方法(删除对象)中,
delete
的操作数的值可以是空指针值,指向前一个<创建的非数组对象的指针em> new-expression ,或指向表示此类对象的基类的子对象(1.8)的指针(第10条)。如果不是,则行为未定义。
由于int[1]
是一个数组对象,如果您尝试使用delete
而不是delete[]
删除它,则行为未定义。
答案 1 :(得分:6)
规则很简单:
new
与delete
new[]
与delete[]
否则你会得到未定义的行为。
没有例外;偶数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
。
由新表达式创建的对象(具有动态存储的对象) duration)持续到新表达式返回的指针为止 用于匹配 delete-expression。
因此,您应该使用delete[]
来释放内存,否则就会出现未定义的行为。
和(incase),如果编译器足够聪明,可以int * arr = new int[1]
作为int
,那么它必须足够聪明,可以delete[] arr
arr
1}}为delete arr
。 但,delete
无法区分arr
与int*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;
c
和a
变量有可能存储在指针ptr
指向的位置旁边,如果a
存储在其旁边,则它还会删除“a
”,如果存在其他数据类型,则会导致意外的运行时结果。
因此建议仅使用delete[]
删除使用新数据类型[]
分配的内存。希望这很有用。