繁体   English   中英

新的char上的C ++ delete [];

[英]C++ delete[] on new char;

请考虑以下代码:

int main()
{
    char* str = new char; 
    str[0] = 'a'; 
    delete[] str; //Notice the []
}

它编译,运行并且没有崩溃(VC15和g ++)它确实有1个内存泄漏,我可以用valgrind清楚地看到它。

但是,如果我运行以下代码:

#include <iostream>

class Foo{
public:
    Foo(){
        std::cout << "Foo::Foo" << std::endl;
    }
    ~Foo(){
        std::cout << "Foo::~Foo" << std::endl;
    }
};

int main()
{   
      Foo* foo = new Foo;
      delete[] foo;
      return 0;
}

在Windows上运行时,我得到一个无限循环的析构函数调用,在Linux中运行一个无效的指针错误(在~20 d调用之后)。

我无法弄清楚为什么两者之间存在差异? 为什么我没有new char或崩溃的无限循环?

你应该使用delete[]和仅使用new[]分配的指针;

问题

在您的第一个代码段中:

  • 用语句char* str = new char; 你得到一个指向单个字符的指针。 所以new的类型匹配char*
  • 但是你的delete[]需要一个指向char数组的指针,所以当你删除一个不是数组的东西时会得到未定义的行为(UB)

第二个代码段具有完全相同的问题。 UB未定义,可以给出奇怪和无法解释的结果。

怎么解决?

对单个元素分配使用单个元素delete:

  Foo* foo = new Foo;
  delete foo;

或者使用数组删除进行数组分配:

  Foo* foo = new Foo[1];
  delete[] foo;

或者更好:摆脱任何你想要使用的新/删除并使用向量而不是数组。

为了简化这一点,对于未使用new[]分配且不为null的指针调用delete[]始终是未定义的

我引用cppreference.com

由delete [] - 表达式调用,以释放先前为对象数组分配的存储。 除非ptr是空指针或者是先前从operator new或operator new [](size_t,std :: nothrow_t)的标准库实现获得的指针,否则此函数的标准库实现的行为是未定义的

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM