简体   繁体   English

使用与new中使用的类型不同的指针删除内存是否安全?

[英]Is it safe to delete memory with a pointer of different type than the used in new?

Is the following code safe? 以下代码是否安全? Is there a reference to C++ standard addressing this question? 有没有提到C ++标准来解决这个问题?

// SomeStruct is POD: no constructors or destructor
SomeStruct *pSS = new SomeStruct();
void *pV = reinterpret_cast<void*>(pSS);
delete pV;

This is only OK when: 这只适用于:

  1. you delete a pointer-to-base, 你删除指向基地的指针,

  2. and that base class has a virtual destructor. 并且该基类具有虚拟析构函数。

Otherwise, you're in the land of illegal code and undefined behaviour. 否则,你处于非法代码和未定义行为的境地。

C++14 5.3.5/2 C ++ 14 5.3.5 / 2

If the operand has a class type, the operand is converted to a pointer type by calling the above-mentioned conversion function, and the converted operand is used in place of the original operand for the remainder of this section. 如果操作数具有类类型,则通过调用上述转换函数将操作数转换为指针类型,并使用转换后的操作数代替本节其余部分的原始操作数。 In the first alternative ( delete object ), the value of the operand of delete may be a null pointer value, a pointer to a non-array object created by a previous new-expression , or a pointer to a subobject (1.8) representing a base class of such an object (Clause 10). 在第一种方式( 删除对象 )的操作数的值delete可以是空指针值,指针到由先前新表达式创建的非阵列对象,或一个指向子对象(1.8)表示这种对象的基类(第10条)。 If not, the behavior is undefined. 如果不是,则行为未定义。 In the second alternative ( delete array ), the value of the operand of delete may be a null pointer value or a pointer value that resulted from a previous array new-expression . 在第二种方式( 删除阵列 )的操作数的值delete可以是空指针值或起因于先前阵列新表达的指针值。 If not, the behavior is undefined. 如果不是,则行为未定义。 [ Note: this means that the syntax of the delete-expression must match the type of the object allocated by new , not the syntax of the new-expression . [ 注意:这意味着delete-expression的语法必须与new分配的对象的类型匹配,而不是new-expression的语法。 end note ] [ Note: a pointer to a const type can be the operand of a delete-expression ; - 结束注释 ] [ 注意:指向const类型的指针可以是delete-expression的操作数; it is not necessary to cast away the constness (5.2.11) of the pointer expression before it is used as the operand of the delete-expression . 在将指针表达式用作delete-expression的操作数之前,不必丢弃指针表达式的constness(5.2.11)。 end note ] - 结束说明 ]

C++14 5.3.5/3 C ++ 14 5.3.5 / 3

In the first alternative ( delete object ), if the static type of the object to be deleted is different from its dynamic type, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined. 在第一个备选( 删除对象 )中,如果要删除的对象的静态类型与其动态类型不同,则静态类型应为要删除的对象的动态类型的基类,静态类型应具有虚拟析构函数或行为未定义。 In the second alternative ( delete array ) if the dynamic type of the object to be deleted differs from its static type, the behavior is undefined. 在第二个备选( 删除数组 )中,如果要删除的对象的动态类型与其静态类型不同,则行为未定义。

Additionally, void is an incomplete type (C++14 3.9.1/9): 另外, void是一种不完整的类型(C ++ 14 3.9.1 / 9):

The void type has an empty set of values. void类型具有一组空值。 The void type is an incomplete type that cannot be completed. void类型是不完整的类型,无法完成。 It is used as the return type for functions that do not return a value. 它用作不返回值的函数的返回类型。 Any expression can be explicitly converted to type cv void (5.4). 任何表达式都可以显式转换为cv void (5.4)类型。 An expression of type void shall be used only as an expression statement (6.2), as an operand of a comma expression (5.19), as a second or third operand of ?: (5.16), as the operand of typeid , noexcept , or decltype , as the expression in a return statement (6.6.3) for a function with the return type void , or as the operand of an explicit conversion to type cv void . void类型的表达式只能用作表达式语句(6.2),作为逗号表达式(5.19)的操作数,作为?: 5.16)的第二个或第三个操作数,作为typeidnoexcept或者操作数的操作数。 decltype ,作为返回类型为void的函数的return语句(6.6.3)中的表达式,或者作为显式转换为cv void类型的操作数。


Also, unless you're interfacing with a C API, void* is something you should strive to avoid completely. 此外,除非您与C API接口,否则您应该努力避免使用void*

Not only it is illegal, it is simply a compilation error on modern compilers. 它不仅是非法的,它只是现代编译器的编译错误。 Can't delete void*. 无法删除void *。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM