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

时间:2016-10-30 15:31:23

标签: c++

请考虑以下代码:

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&#39; tors调用之后)。

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

2 个答案:

答案 0 :(得分:5)

您应使用delete[]并且仅使用使用new[]分配的指针;

问题

在您的第一个代码段中:

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

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

如何解决?

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

  Foo* foo = new Foo;
  delete foo;

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

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

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

答案 1 :(得分:1)

要做到这一点,请调用delete[]以获取未使用new[]而非null分配的指针始终 undefined

我引用cppreference.com

  

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