当我在C ++中对未初始化的指针调用“delete”时会发生什么?

时间:2014-11-25 17:31:21

标签: c++ pointers memory memory-management

让我说我声明了一个char的指针,并在没有调用new的情况下调用delete。这会导致问题吗?

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,因为如果//do more stuff为真,condition中的另一个指针可以指向它。显然,如果condition为真,这种方法可行,因为" new"在myptr被召唤。如果我输入其他条件,myptr未使用,则删除myptr是否错误?

4 个答案:

答案 0 :(得分:13)

未定义的行为指针必须来自new或必须是空指针。

标准(N3797)5.3.5 [expr.delete] / 2

  

如果操作数具有类类型,则操作数将转换为指针   通过调用上面提到的转换函数来键入   转换后的操作数用于代替原始操作数   本节的其余部分。 在第一个替代(删除对象)中,   delete的操作数的值可以是空指针值,a   指向由前一个new-expression创建的非数组对象的指针,或   指向表示这种类的基类的子对象(1.8)的指针   对象(第10条)。如果不是,则行为未定义   [...]

delete []底部遗漏的部分相同。

删除仅对

有效
  • 空指针
  • 你从新的
  • 指针
  • 或指向上面的基类指针。

空指针:

要跟进空指针,在空指针上调用delete是一个noop,之后指针仍然是一个空指针(无需重新分配nullptr)。这至少对于标准delete和解除分配函数是有保证的。如果您定义自定义的,您也应该正确处理。

标准5.3.5 [expr.delete] / 7

  

如果delete-expression的操作数的值不是空指针值,则:

     
      
  • [...]
  •   
     

否则,未指定是否将调用释放函数。 [注意:无论对象的析构函数或数组的某个元素是否抛出,都会调用释放函数   例外。 - 结束说明]

所以delete可能什么都不做,或者可能用空指针调用deallocation函数。让我们看看下一个功能:

标准3.7.4.2 [basic.stc.dynamic.deallocation] / 3

  

如果通过抛出异常终止释放函数,则行为未定义。 提供给解除分配函数的第一个参数的值可以是空指针值;如果是这样,并且如果解除分配功能是标准库中提供的功能,则该呼叫无效   [...]

明确提到它没有效果。

注意:如果您定义自己的自定义释放功能,则应确保以相同的方式处理它。不正确处理空指针将是邪恶的。

答案 1 :(得分:3)

如果指针初始化为nullptr,则删除它将是安全的。

目前,myptr未初始化,尝试删除它的值可能会导致分段错误。

char* myptr = nullptr将在c ++ 11或更高版本中解决此问题,或者对c ++ 98或更早版本使用0NULL

答案 2 :(得分:2)

这将是一个未定义的行为。必须使用new。

在指针分配的内存上调用delete

但是你可以安全地调用null指针上的delete。

答案 3 :(得分:2)

你可以像

一样写
char* myptr=NULL;

if (condition)
    //do something involving myptr = new char[SIZE];
else
    //do something that doesnt involve myptr

//do more stuff
if(myptr)
  delete[] myptr;