Destructor
Destructor

Reputation: 14438

Why is freeing invalid pointers left undefined in C++?

Consider following program:

#include <iostream>
int main()
{
    int b=3;
    int* a=&b;
    std::cout<<*a<<'\n';
    delete a;  // oops disaster at runtime undefined behavior
}

Ok, behavior of program is undefined according to C++ standard. But my question is why it is left undefined? Why implementations of C++ don't give any compiler errors or any warnings? Is it really hard to determine validity of pointer (means to check whether pointer is returned by new at compile time?) Is there any overhead involved to determine validity of pointer statically (i.e. compile time)?

Upvotes: 4

Views: 268

Answers (4)

Here is the implementation detail answer:

The new/delete implementation has to have some way to keep track of some data about all blocks allocated via new, especially about their size. Usually, this is done by storing this data in the bytes before the start of the allocated block. That way, the implementation of delete can very quickly determine how to handle the block. Of course, if you pass in an invalid address, the delete implementation will only find bogus data there, possibly crashing your application or silently corrupting data. But that's ok since passing in an invalid address is undefined behavior.

Now, what would be the consequences of making it legal to pass invalid pointers?
The new/delete implementation would not be able to just look up this information from the pointer that's passed in, because that might be bogus information. The only way to retrieve the necessary information would be to look up the given pointer in a table of currently valid pointers. Such a lookup is quite expensive, even if fast lookup algorithms are used; a lot slower than just dereferencing the given pointer, anyway.

So it's all about a speed/safety trade-off once again, and C++ opted for speed in this instance.

Upvotes: 3

kirillbobyrev
kirillbobyrev

Reputation: 1739

Why implementations of C++ don't give any compiler errors or any warnings?

Clang Static Analyzer does it.

For your piece of code you can get:

$ scan-build clang++ main.cpp
scan-build: Using '/usr/bin/clang' for static analysis
main.cpp:7:5: warning: Argument to 'delete' is the address of the local variable 'b', which is not memory allocated by 'new'
    delete a;  // oops disaster at runtime undefined behavior
    ^~~~~~~~
1 warning generated.
scan-build: 1 bug found.

As mentioned, it's not always possible to determine whether a pointer is valid or not at compile time, but Static Analyzer can definitely help in you your case.

Upvotes: 7

Simon Gibbons
Simon Gibbons

Reputation: 7194

Determining if a pointer is valid at compile time is impossible to do in the general case. For example if you have a function as part of a library that takes a pointer as an argument, the compiler cannot determine that it will always have a valid pointer passed to it.

The standard leaves deletion of invalid pointers as undefined behavior as otherwise a check would have to be made at runtime every time a pointer is deleted, or indeed dereferenced, this would incur a performance penalty that the language designers didn't want.

Upvotes: 9

imreal
imreal

Reputation: 10378

It is impossible to determine what a pointer points to at compile time, here is an example to illustrate this:

volatile bool newAlloc;

int main()
{
   int b=3;
   int* a;
   if(newAlloc)
   {
       a = new int;
   } else {
       a = &b;
   }
   std::cout<<*a<<'\n';
   delete a;  // impossible to know what a will be
}

Upvotes: 14

Related Questions