I have two blocks of code about new[]
and delete[]
:
1)
#include <string>
int main()
{
std::string *p = new std::string[0];
delete[] p;
return 0;
}
2) In this case, I merely change std::string
to int
int main()
{
int *p = new int[0];
delete[] p;
return 0;
}
My question is:
Why the first program crashes with the following message (in linux environment):
Segmentation fault (core dumped)
But the second program works well without any error?
EDIT
compiler: g++ (Ubuntu/Linaro 4.7.2-2ubuntu1) 4.7.2
I just use g++
without any argument to compile it.
If it is a compiler bug, should they crash or not according to the standard?
This should be a gcc bug. That the whole new[]
expression is ignored and p
becomes uninitialized, and then we delete[]
an uninitialized pointer which crashes. If we compile the program with -Wall
it will warn you that
warning: ‘p’ is used uninitialized in this function
which is clearly wrong. The expression new X[0]
is well-defined in both C++03 and C++11 (§5.3.4/7), and this works correctly in clang, so the only logical conclusion is that it's a gcc bug.
The elimination-of-new[]
bug only exists when the type to be constructed has any non-trivial constructor. And the segfault happens the type has a destructor, because the delete[]
will then need to dereference that uninitialized pointer. Therefore, it crashes for std::string
but not int
, because int
is trivial and std::string
is not.
This can be worked around by using an intermediate variable, such that the expression cannot be evaluated to 0 directly:
size_t length = 0;
std::string* p = new std::string[length];
// ...
delete[] p;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With