views:

163

answers:

6

Consider the following situation:

SomeType *sptr = someFunction();
// do sth with sptr

I am unaware of the internals of someFunction(). Its pretty obvious that the pointer to the object which someFunction() is returning must be either malloc'ed or be a static variable.

Now, I do something with sptr, and quit. clearly the object be still on the heap which is possibly a source of leak.

How do I avoid this?

EDIT:

Are references more safer than pointers. Do the destructor for SomeType would be called if I do :

{
  SomeType &sref = *sptr;
}

Any insights.

+3  A: 

What do you mean by quit? End the process? Your heap is usually destroyed when the process is destroyed. You would only get a leak potential after quitting the process if your asked the operating system to do something for you (like get a file or window handle) and didn't release it.

Also, functions that return pointers need to document very well whose responsibility it is to deallocate the pointer target (if at all), otherwise, you can't know whether you need to delete it yourself or you could delete it by accident (a disaster if you were not meant to do so).

If the documentation of the function doesn't tell you what to do, check the library documentation - sometimes a whole library takes the same policy rather than documenting it in each and every function. If you can't find the answer anywhere, contact the author or give up on the library, since the potential for errors is not worth it, IMHO.

In my experience most functions that return a pointer either allocate it dynamically or return a pointer that is based on the input parameter. In this case, since there are no arguments, I would bet that it is allocated dynamically and you should delete it when you're done. But programming shouldn't be a guessing game.

Uri
+19  A: 

You need to read the documentation on someFunction. someFunction needs to clearly define the ownership of the returned pointer (does the caller own it and need to call delete or does someFunction own it and will make sure the the object is destructed sometime in the future).

If the code does not document it's behavior, there is no safe way to use it.

R Samuel Klatchko
This is the right answer- someFunction should tell you how to clean up after it.
DeadMG
@DeadMG: I disagree, `someFunction` should take responsibility for any object it allocates or returns something better than a bare pointer so that the compiler enforces the ownership. `telling` is like having a little excerpt *Don't call with a null pointer*: express contracts in code, not comments.
Matthieu M.
@Matthieu: Not every ownership scheme requires a specific class to express it. For example, if these objects don't need deletion, what class do you use for that? std::non_destructing_ptr? In addition, what if the interface is supposed to be C compat?
DeadMG
If they don't need deletion, or rather if deletion is not of the responsability of the client, then I use a bare pointer :) C compatibility is something different altogether.
Matthieu M.
Totally agree with DeadMG. It is fully possible in C++ to unambiguously specify the ownership of objects across API boundaries in code using smart pointers. If ownership of an object is transferred, it should be done with a smart pointer. If a client acquires a raw pointer they should not presume to delete it.
bshields
@bshields, while I agree with your sentiment, it is not always the case where you have control over the interface of a function (think third-party libs). If in doubt, read the manual or the source. Personally, I prefer to return `std::auto_ptr` if I'm intending to transfer non-shared ownership and return a raw pointer (or reference) if the called function maintains ownership.
Nathan Ernst
A: 

It's always a good habit to clean up after yourself, don't presume the OS will do it;

There's a good change your IDE or debugger will report memory leak when you quit your application.

What do you have to do ? Well, it depends, but normally you have to release the memory allocated by someFunction(), and the documentation will probably help you with that, either there's an API to release the memory or you have to do it manually with free or delete.

Max

Max
The question is how you know whether the pointer should be deleted. If it's a pointer to new'd memory, it's a bad thing if it's not deleted. If it's a pointer to static memory, it's a REAL bad thing if it's deleted.
David Thornley
A: 

The library should document this. Either you delete it explicitly after use or you call some release method which makes sure that object (and any other resources it points to*) doesn't leak.

(given a choice) Unless its a huge (in terms of memory) object, I would rather prefer a return by value. Or pass a reference to the function.

neal aise
A: 

If someFunction returns an object for me it should be normal to have a pair function like someFunctionFree which you'll call to release the resources of the SomeType object. All the things needed should be found in the documentation of someFunction (mainly how the object can be freed or if the object is automatically freed). I personally prefer the corresponding deallocation function (a CreateObject/DestroyObject pair).

Iulian Şerbănoiu
A: 

As others note it's up to the function to enforce it's ownership assumptions in code. Here's one way to do that using what's known as smart pointers:

#include <iostream>
#include <boost/shared_ptr.hpp>

struct Foo
{ 
  Foo( int _x ) : x(_x) {}
  ~Foo() { std::cout << "Destructing a Foo with x=" << std::hex << x << "\n"; }
  int x;
};

typedef boost::shared_ptr<Foo> FooHandle;

FooHandle makeFoo(int _x = 0xDEADBEEF) {
    return FooHandle(new Foo(_x));
}

int main()
{
    {
        FooHandle fh = makeFoo();
    }
    std::cout<<"No memory leaks here!\n";

    return 0;
}
Robert S. Barnes