我可以对单个元素数组分配使用“operator delete[]”吗
Can I use `operator delete[]` for a single element array allocation?
如果我们将大小为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 int
和new int[1]
很可能在掩护下做完全相同的事情,但如果是这种情况,那么delete[]
上的int*
和delete
在int*
上也会做完全一样的事情。)
ISO/IEC 14882:2011 5.3.5[expr.delete]/2:
在第一种可选方案(删除对象)中,
delete
的操作数的值可以是空指针值、指向由以前的新表达式创建的非数组对象的指针,或者指向表示此类对象基类的子对象(1.8)的指针(第10条)。如果不是,则行为未定义。
由于int[1]
是一个数组对象,如果尝试使用delete
而不是delete[]
删除它,则行为是未定义的。
规则很简单:
- 始终平衡
new
和delete
- 始终平衡
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
无法区分arr
、int*arr = new int[1]
和int*arr = new int
。delete
中的[]
将指示它。
不,这是不安全的,可能会导致一些不必要的情况
例如,在内存中,指针指向的位置旁边可能有一些数据(int/char/float
…)。此时,如果您使用delete []
,则如果该数据是整数,它可能也会尝试删除该数据,对于其他数据类型,它会导致意外错误。
示例:
int *ptr = new int;
int a = 20;
char c = 'e';
*ptr = 10;
delete [] ptr;
c
和a
变量可能存储在指针ptr
指向的位置旁边。如果a
存储在它旁边,则它会删除"a
"。如果存在其他数据类型,则会导致意外的运行时结果。
因此,建议仅在删除使用新数据类型[]
分配的内存时使用delete[]
。希望这有用。
- 运算符C++ "delete []"仅删除 2 个前值
- 为什么 std::optional::operator=(U&&) 要求你是非标量类型?
- 'operator='已弃用:改用 QDir::setPath()
- 过载'operator new'如何导致无限循环?
- g++用户定义的动态链接库上的全局new和delete运算符
- 为什么"delete"关键字不删除节点?
- 与'operator='不匹配(操作数类型'String'且"void")
- "delete"在 C++ 中实际上做了什么?
- C++和组装:通过ASM呼叫'operator new'和'operator delete'
- 什么是"::operator new"和"::operator delete"?
- 我可以对单个元素数组分配使用“operator delete[]”吗
- 正在对使用operator new okay的放置delete操作的结果调用delete
- g++ 4.9.0允许对位置分配使用operator delete[](void*, size_t)
- 为什么"const T*"在"operator delete"中被简单地转换为"void*"?
- c++ 14是否要求delete表达式必须调用' void operator::delete(void*, std::
- 为什么 gcc 4.9.0 中没有定义"void operator delete(void* ptr, std::size_t size) noexcept;"?
- 线程清理器报告使用嵌入式参考计数器时"data race on operator delete(void*)"
- visual C++ Delete Operator
- :operator delete(void*)是否知道使用::operator new(size_t)分配的内存大小
- 替换函数'operator new'不能声明'inline' [-werror,-winline-new-delete]