当我打电话给“删除"时,会发生什么情况?在C ++中未初始化的指针上? [英] What happens when I call "delete" on an uninitialized pointer in C++?
问题描述
比方说,我声明了char的指针,并在不调用new的情况下对其调用了delete.这会引起问题吗?
Let's say I declare a pointer of char, and call delete on it without having called new. Can this cause a problem?
char* myptr;
if (condition)
//do something involving myptr = new char[SIZE];
else
//do something that doesnt involve myptr
//do more stuff
delete[] myptr;
我不会删除if下的myptr,因为如果condition
为true,则//do more stuff
中的另一个指针可以指向它.显然,如果condition
为true,则可以正常工作,因为在myptr
上调用了"new".如果我输入了未使用myptr
的else条件,删除myptr
是否不好?
I don't delete myptr under the if because another pointer in //do more stuff
can point to it if condition
was true. Obviously this works fine if condition
was true because a "new" was called on myptr
. Is deleting myptr
bad if I entered the else condition, where myptr
is unused?
推荐答案
这是未定义的行为.指针必须来自new
或必须为空指针.
It's undefined behavior. The pointer must come from new
or must be a null pointer.
标准(N3797)5.3.5 [expr.delete]
/2
Standard (N3797) 5.3.5[expr.delete]
/2
如果操作数具有类类型,则将操作数转换为指针 通过调用上述转换函数输入 转换后的操作数用于代替原始操作数 本节的其余部分. 在第一个替代方法(删除对象)中, delete的操作数的值可以是空指针值, 指向由先前的new表达式创建的非数组对象的指针,或者 指向子对象(1.8)的指针,该子对象表示此类对象的基类 对象(第10条).如果不是,则行为是不确定的.
[...]
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). If not, the behavior is undefined.
[...]
在底部遗漏的部分与delete []
相同.
The part left out at the bottom is the same for delete []
.
删除仅对
- 空指针
- 您从新手那里获得的指针
- 或指向上面的基类指针.
要跟进空指针,在空指针上调用delete
是noop,此后指针仍然是空指针(无需为它重新分配nullptr
).至少对于标准delete
和释放函数,这是可以保证的.如果定义自定义变量,则也应正确处理.
To follow up on null pointers, calling delete
on a null pointer is a noop and the pointer is still a null pointer afterwards (no need to reassign nullptr
to it). This is guaranteed at least for the standard delete
and deallocation functions. If you define custom ones you should also handle this properly.
标准5.3.5 [expr.delete]
/7
Standard 5.3.5 [expr.delete]
/7
如果delete-expression的操作数的值不是空指针值,则:
If the value of the operand of the delete-expression is not a null pointer value, then:
- [...]
- [...]
否则,不确定是否将调用释放函数. [注:无论对象的析构函数还是数组的某些元素抛出异常,都会调用释放函数. 例外. —尾注]
Otherwise, it is unspecified whether the deallocation function will be called. [ Note: The deallocation function is called regardless of whether the destructor for the object or some element of the array throws an exception. — end note ]
因此,delete
可能根本不执行任何操作,或者可能使用空指针调用释放函数.接下来让我们看一下该功能:
So delete
might do nothing at all or might call the deallocation function with the null pointer. Lets look at that function next:
标准3.7.4.2 [basic.stc.dynamic.deallocation]
/3
Standard 3.7.4.2 [basic.stc.dynamic.deallocation]
/3
如果释放函数因引发异常而终止,则行为未定义. 提供给释放函数的第一个参数的值可以为空指针值;如果是这样,并且如果释放函数是标准库中提供的函数,则该调用无效.
[...]
If a deallocation function terminates by throwing an exception, the behavior is undefined. The value of the first argument supplied to a deallocation function may be a null pointer value; if so, and if the deallocation function is one supplied in the standard library, the call has no effect.
[...]
明确提到它没有任何作用.
It is explicitly mentioned that it got no effect.
注意:如果您定义自己的自定义释放函数,则应确保以相同的方式处理它.不正确处理空指针将是邪恶的.
Note: If you define your own custom deallocation functions you should make sure you handle it the same way. Not handling null pointers properly would be evil.
这篇关于当我打电话给“删除"时,会发生什么情况?在C ++中未初始化的指针上?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!