简体   繁体   English

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

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

Consider the following code: 请考虑以下代码:

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

It compiles, runs and nothing crashes (VC15 and g++) It does however have 1 memory leak which I can clearly see with valgrind. 它编译,运行并且没有崩溃(VC15和g ++)它确实有1个内存泄漏,我可以用valgrind清楚地看到它。

If I run the following code however: 但是,如果我运行以下代码:

#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;
}

I get an infinite loop of destructor calls when running on Windows, and an invalid pointer error in Linux (after ~20 d'tors calls). 在Windows上运行时,我得到一个无限循环的析构函数调用,在Linux中运行一个无效的指针错误(在~20 d调用之后)。

What I can't figure out is why is there a difference between the two? 我无法弄清楚为什么两者之间存在差异? why don't I get an infinite loop with new char or crash? 为什么我没有new char或崩溃的无限循环?

You shall use delete[] with and only with a pointer which was allocated using new[] ; 你应该使用delete[]和仅使用new[]分配的指针;

The problem 问题

In your first code snippet: 在您的第一个代码段中:

  • With the statement char* str = new char; 用语句char* str = new char; you get a pointer to a single char. 你得到一个指向单个字符的指针。 So the type from new matches the char* . 所以new的类型匹配char*
  • But your delete[] expects a pointer to an array of char, so you get undefined behavior (UB) when you delete something that is not an array 但是你的delete[]需要一个指向char数组的指针,所以当你删除一个不是数组的东西时会得到未定义的行为(UB)

The second code snippet has exactly the same problem. 第二个代码段具有完全相同的问题。 UB is undefined and can give strange and unexplainable results. UB未定义,可以给出奇怪和无法解释的结果。

How to solve it ? 怎么解决?

Either use a single element delete for a single element allocation: 对单个元素分配使用单个元素delete:

  Foo* foo = new Foo;
  delete foo;

Or use an array delete for an array allocation: 或者使用数组删除进行数组分配:

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

Or better: get rid of any new/delete you're tempted to use and use vectors instead of arrays. 或者更好:摆脱任何你想要使用的新/删除并使用向量而不是数组。

To make this short, calling delete[] for a pointer that was not allocated with new[] and is not null is always undefined 为了简化这一点,对于未使用new[]分配且不为null的指针调用delete[]始终是未定义的

I quote from cppreference.com : 我引用cppreference.com

Called by delete[]-expressions to deallocate storage previously allocated for an array of objects. 由delete [] - 表达式调用,以释放先前为对象数组分配的存储。 The behavior of the standard library implementation of this function is undefined unless ptr is a null pointer or is a pointer previously obtained from the standard library implementation of operator new or operator new[](size_t, std::nothrow_t). 除非ptr是空指针或者是先前从operator new或operator new [](size_t,std :: nothrow_t)的标准库实现获得的指针,否则此函数的标准库实现的行为是未定义的

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

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