ZivS ZivS - 1 month ago 17
C++ Question

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.

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).

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?

Answer

You shall use delete[] with and only with a pointer which was allocated using new[];

The problem

In your first code snippet:

  • With the statement char* str = new char; you get a pointer to a single char. So the type from new matches the 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

The second code snippet has exactly the same problem. UB is undefined and can give strange and unexplainable results.

How to solve it ?

Either use a single element delete for a single element allocation:

  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.