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

2024-03-20

假设我声明了一个 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是真的,因为调用了“新”myptr。正在删除myptr如果我进入 else 条件就不好了,其中myptr未使用?


It's 未定义的行为。指针must来自new或者必须是空指针。

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

如果操作数具有类类型,则操作数将转换为指针 通过调用上述转换函数来类型化,并且 转换后的操作数用于代替原始操作数 本节的其余部分。在第一个替代方案(删除对象)中, delete操作数的值可以是空指针值,a 指向由先前的 new 表达式创建的非数组对象的指针,或者 指向代表此类基类的子对象 (1.8) 的指针 对象(第 10 条)。如果不是,则行为未定义。
[...]

底部留下的部分是相同的delete [].

删除仅对以下有效

  • 空指针
  • 你从 new 得到的指针
  • 或指向上面的基类指针。

空指针:

要跟踪空指针,请调用delete空指针上是一个 noop 并且该指针之后仍然是一个空指针(不需要重新分配nullptr到它)。至少对于标准来说这是有保证的delete和解除分配函数。如果您定义了自定义的,您也应该正确处理这个问题。

标准5.3.5[expr.delete]/7

如果删除表达式的操作数的值不是空指针值,则:

  • [...]

否则,未指定是否会调用释放函数。[ 注意:无论对象或数组的某些元素的析构函数是否抛出异常,都会调用释放函数 例外。 ——尾注]

So delete可能什么也不做,或者可能使用空指针调用释放函数。接下来让我们看看这个函数:

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

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

明确提到它没有效果。

Note:如果您定义自己的自定义释放函数,您应该确保以相同的方式处理它。不正确处理空指针将是邪恶的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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