我想知道如果我尝试对已经删除但可能尚未分配的指针执行delete
会有什么影响?我读过两件事:第一,delete
运算符会做一些检查,我们不需要检查指针是否为空;然后,我读到它会导致未知的行为..
我问它,因为我使用了一些包含Qt对象属性的个人对象;我认为Qt会删除关闭窗口时关联的所有小部件,但我不确定并且仍然如此:如果在窗口关闭之前软崩溃,我们必须手动删除所有对象。
那么,什么是最好的解决方案?那样的东西?
if( my_object )
delete my_object;
可以避免危险行为吗?
答案 0 :(得分:14)
delete
d非空指针上的 delete
是未定义的行为 - 您的程序可能会崩溃。您可以安全地在空指针上使用delete
- 它将产生一个无操作。
所以真正的问题不是空指针上的delete
。真正的问题在于:
ptr = new Something();
otherPtr = ptr;
delete ptr;
delete otherPtr;
如果您有多个指向同一个对象的指针并且非常危险,则会发生这种情况。可能的解决方案是:
delete
)或delete
恰好在恰当的时间。答案 1 :(得分:4)
if( my_object )
delete my_object;
是多余的。 delete
指针上的NULL
什么都不做。这是由标准保证的。
delete
会导致未定义的行为。这就是为什么你应该总是记得在删除它们之后将指针分配给NULL
:
delete p;
p = NULL;
编辑:根据评论,我觉得我应该指明这一点。如果您有多个指向同一对象的指针,则赋值为NULL将不会使删除安全。无论如何,最好使用智能指针。
答案 2 :(得分:1)
请注意,删除指针不会将其设置为NULL。
int* i = new int;
*i = 42;
delete i;
delete i; // oops! i is still pointing to the same memory, but it has been deleted already
删除空指针不会执行任何操作,删除已删除的对象将导致未定义的行为。
答案 3 :(得分:1)
正确的方法是:
if( my_object )
{
delete my_object;
my_object = NULL;
}
因为,以前的方式调用两次会在delete
指针上调用deleted
。
答案 4 :(得分:0)
如果您在已经delete
d指针上调用delete
,则会导致未定义的行为。
尽管在delete
指针上调用NULL
没有效果。
标准c ++03§3.7.4.2-3
如果通过抛出异常终止释放函数,则行为未定义。提供给解除分配函数的第一个参数的值可以是空指针值;如果是这样,并且如果解除分配功能是标准库中提供的功能,则该呼叫无效。否则,提供的值 标准库中的运算符
delete(void*)
应该是先前调用标准库中的运算符new(std::size_t)
或operator new(std::size_t, const std::nothrow_-t&)
返回的值之一,并且值提供给运算符{{1标准库中的标签库应该是前一次调用delete[](void*)
或者返回的值之一 标准库中的operator new[](std::size_t)
。
使用 RAII&智能指针是避免此类问题的最佳武器。
答案 5 :(得分:0)
只是结合上面的答案:
总结一下:您必须清楚谁拥有该对象以及指向该对象的不同指针所在的位置。删除对象时,请确保将指向该位置的所有指针都设置为0 / NULL。使用管理对象(如boost :: shared_pointer或QPointer)来帮助您完成此任务。