简体   繁体   中英

c++ reference to pointer: inconsistent segfault

I am working with a collaboration on a big project. Due to our code's infrastructure, basically all functions must "return by reference":

void doSomething(TYPE &result) {
  // do something to result
}

However, I am running into some Segmentation Errors when trying to use references to pointers. Especially when I try to clean up the memory, bad things happen. To try and understand the segfaults, I made a very simple test code. My first attempt compiled and ran without any errors:

int main() {
  int* a;

  delete a;  // Seems to cause no problem!
}

Since this worked, I decided to try something similar with a reference to a pointer:

int main() {
  int* a;

  delete a;  // Suddenly, this line is an "invalid delete".
  int*& b = a;
}

Why does this suddenly segfault? Also, if a "proper way" exists to clean up the memory reserved by a pointer via a reference, what is it?

Some research notes:

I tried to find some answers here on StackOverflow. It should be safe to delete a NULL pointer according to Is it safe to delete a NULL pointer? ... My pointer is totally uninitialized, so I might be doing something silly. However, in my big collaboration code, I would have to dig pretty deep to initialize this kind of pointer to NULL.

I also tried to learn about references to pointers in general. Another StackOverflow post suggested http://markgodwin.blogspot.co.il/2009/08/c-reference-to-pointer.html . That was a good read, but didn't solve my problem.

Thanks in advance!

Calling delete on an uninitialized pointer yields undefined behavior. Therefore it might not cause you problems sometimes but can crash other times.

Any type of access performed on an uninitialized variable (apart from initializing it) leads to undefined behavior. eg reading it, comparing it, deleting it.

You're mistaken if you think that an uninitialised pointer will be NULL . It is actually uninitialised, and accessing its value causes undefined behaviour.

A statement delete a accesses the value of a which causes undefined behaviour in itself.

Using operator delete on any non-NULL pointer that was not produced by the corresponding operator new gives undefined behaviour (whether that pointer has a valid value or not).

Undefined behaviour can give any result. Including inconsistency like your describe.

Your example is not great because "a" will only be NULL in debug mode and will be undefined in release mode. It could contain any random value.

You may want to create your objects on stack, like this:

void foo() {
 TYPE myObj; // this calls the default c-tor, creating the obj on stack
 // the object will de destroyed when the executions goes out of scope.
 // if you pass the object reference to another function that keeps the 
 // reference for future use you are in trouble, as the object will be 
 // destroyed when out of this scope...

}

Alternatively, create the object on heap, using new :

void foo() {
     TYPE * myObj = new TYPE(); // here you need to take care of 
     // destroying the object yourself  (delete myObj)

    }

Best is to use smart pointers. Check Boost, highly recommend. http://www.boost.org/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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