tags:

views:

104

answers:

4
int* test( )
{
    int a = 5;
    int* b = &a;
    return b;
}

Will the result of test be a bad pointer? As far as I know a should be deleted and then b would become a messed up pointer, right?

How about more complicated things, not an int pointer but the same with a class with 20 members or so?

+6  A: 

The term for what you're returning is a "dangling pointer". a is a local variable allocated on the stack, and it is no longer available once it goes out of scope (which is something completely different from garbage collection). Attempting to use the result of a call to test() will be undefined behavior.

On the other hand, if you didn't allocate a on the stack -- (int *a = new int(5);), then int *b = a; return b; would be just fine, although not as good as return new int(5). However, if you don't properly free the result later, you will have a memory leak.

Mark Rushakoff
Okay - and is there any way to solve this? To make the value persist so I don't have to define it elsewhere?
oh boy
What exactly is your goal? Returning a pointer to the same object every time `test()` is called? You could return the address of a static variable, for instance.
Mark Rushakoff
+4  A: 

Yes, it's a pointer to something that no longer exists, the local variable called a. Whether a is an int, an array, an instance of a class makes no difference. And c++ does not have garbage collection.

In this case, and in many others, you should of course return a copy:

int test( )
{
    int a = 5;
    return a;
}

This is true for classes as well as the built-in types.

anon
+1  A: 

The pointer b in this case points to an entity allocated from the stack. That memory will be available to the calling process as soon as this function returns.

If you need to create an object that will outlive the process which created it, you'll need to use malloc() or new to get a block of memory from the heap, and remember to free or delete it later.

David Lively
A: 

Yes, this will give a dangling pointer. If you want the value to persist, you have a couple of possibilities. One is that since you apparently really want to return a value, do exactly that -- return the value instead of a pointer. Another is to allocate the object involved with new, and return a pointer to that dynamically allocated space. This makes deleting the object the responsibility of the caller, however, which can lead to memory leaks and such.

In the end, you generally want to figure out what scope the variable really needs, and have it owned by something (most often an object) with that scope, so it'll be created automatically on entry to the scope, and destroyed automatically on exit from the scope.

If you can't do that, you still need to figure out who "owns" the object, and will be responsible for destroying it as needed. Once in a while that's hard to pin down, and you need something like a reference-counted pointer to keep track of things. At least in my experience, these are used much more often than they really should be though. I've been writing C++ almost as long as anybody outside of AT&T, and haven't needed a shared_ptr yet. A few times, I've thought I'd need it, but eventually figured out a cleaner design the eliminated the requirement.

Jerry Coffin
You can tack shared pointers onto older systems that may do unexpected things, and which you don't want to redesign, and gain a significant amount of safety. Moreover, they're easier to keep correct over years of modification.
David Thornley
@David:Oh, quite true -- I didn't mean to imply that they were useless, or anything like that. At the same time, I tend to think of them as more of a band-aid than how the code really *ought* to be written. There's no question, however, that if/when you have code that's "bleeding" memory, a band-aid can be extremely useful...
Jerry Coffin
@Jerry: They're basically garbage collection, of a fairly primitive and decentralized kind. They're useful wherever garbage collection is, and for large real-life systems I'd rather depend on the GC than on every developer who worked on it in the past ten years.
David Thornley