使用delete[]运算符释放void指针上的内存

3
我们可以使用void*上的delete[]运算符来释放原始数据类型的数组。例如:
char* charPtr = new char[100]
void* voidPtr = (void*)charPtr;
delete[] voidPtr;

或者使用delete运算符释放它,例如:

delete voidPtr

我不希望它调用析构函数。我只期望它释放由new操作符分配的内存。


考虑到您尚未接受答案,它是否存在任何缺失的细节? - Shafik Yaghmour
1个回答

12

这是无效的,如果我们查看C++草案标准5.3.5Delete的话,它就是未定义的行为(我接下来的部分是重点):

操作数必须是指向对象类型或类类型的指针。如果是类类型,则操作数在上下文中隐式转换(第4条)。delete表达式的结果类型为void。78

脚注78说:

意味着不能使用void*类型的指针删除对象,因为void不是对象类型。

另一方面,free允许您使用void*,但必须是通过malloccallocrealloc进行分配的。


为什么当operator delete只接受void*作为参数时会出现未定义的情况?http://en.cppreference.com/w/cpp/memory/new/operator_delete和http://www.cplusplus.com/reference/new/operator%20delete[]/。分配器也是如此。Allocate和Deallocate函数接受`void*`,并且可以正常工作。甚至可以打开MSVC和Mingw头文件查看。 - Brandon
1
@CantChooseUsernames “delete-expression”(删除表达式)与operator delete并不相同。特别是,在调用操作符之前会先调用相关类型的析构函数(这就是为什么操作符只需要一个void*——没有对象了,只有存储空间)。 - molbdnilo
1
@CantChooseUsernames 这里指的是 operator delete,它与 delete expression 不同。导致 UB 的原因是你违反了一个 shall 约束。 - Shafik Yaghmour
@ShafikYaghmour 我同意标准不建议使用void。但我正在寻找的示例分配了char数组,这是一种原始数据类型。在这里,我不希望调用char的析构函数。正如cantChooseusernames指出的那样,delete运算符接收void。因此,在这里通过调用delete[] voidPtr来实现释放内存的目的。 - Ravindra12jan
@Ravindra12jan 它是未定义的,因此编译器可以自由地执行任何操作,甚至可以完全优化掉代码。因此,您不能依赖它。唯一可行的方式是,如果编译器将该情况记录为受支持的情况,但仍然使其不可移植。 - Shafik Yaghmour
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接