【问题标题】:C++: anything wrong with the following code?C++:下面的代码有什么问题吗?
【发布时间】:2013-01-20 13:55:19
【问题描述】:

我得到以下代码:

T *p = new T[10];
delete p;

我认为应该是 delete [] p。我在 T=int 类型上尝试过,没有错误。然后我创建了一个简单的类,异常。有什么明确的解释吗?

T *p = 0;
delete p;

他们有什么问题? [我查了一下,好像虽然delete p会导致错误,但是程序恢复是因为编译器一开始就认为p==0,所以这个错误无所谓。]

【问题讨论】:

    标签: c++ templates pointers memory-management memory-leaks


    【解决方案1】:

    是的,
    你应该打电话给delete [] p;

    有什么明确的解释吗?

    这是未定义的行为:

    • 如果分配是通过new [] 调用delete
    • 在非动态分配的指针上调用delete

    请注意,Undefined Behavior 意味着任何事情都可能发生,它并不强制要求崩溃。它只是意味着您的程序可以显示任何行为(包括按预期工作)。

    NULL 指针上调用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&) 返回的值之一,并且提供给标准库中的操作员delete[](void*) 的值应为先前调用 operator new[](std::size_t) 或返回的值之一 operator new[](std::size_t, const std::nothrow_t&) 在标准库中。

    【讨论】:

      【解决方案2】:

      当您使用new[] 分配对象数组时,您必须使用delete[] 将其删除。否则会导致未定义行为

      deletedelete[] 之间的主要行为区别在于后者除了释放内存外,还调用数组中每个对象的析构函数。

      考虑您的第二点:

      T *p = 0;
      delete p;
      

      这不会导致错误,而是什么都不做,因为这是delete 在指针为空时的预期行为。

      【讨论】:

      • 技术上不准确。调用delete 而不是delete[] 是UB。
      • @LuchianGrigore:同意,我会编辑它。但是,我并不是说你可以打电话给delete 而不是delete[]。相反,我想指出两者之间的行为差​​异是什么。但是,是的,你说得有道理。
      猜你喜欢
      • 2012-11-06
      • 2018-06-27
      • 2019-12-02
      • 1970-01-01
      • 2011-10-10
      相关资源
      最近更新 更多