I know this won\'T work because the variable x gets destroyed when the function returns:
int* myFunction()
{
int x = 4; return &x;
}
<
C++ approach to avoid memory leaks. (at least when You ignore function output)
std::auto_ptr<int> myFunction() {
std::auto_ptr<int> result(new int(4));
return result;
}
Then call it:
std::auto_ptr<int> myFunctionResult = myFunction();
EDIT: As pointed out by Joel. std::auto_ptr has it's own drawbacks and generally should be avoided. Instead std::auto_ptr You could use boost::shared_ptr (std::tr1::shared_ptr).
boost::shared_ptr<int> myFunction() {
boost::shared_ptr<int> result(new int(5));
return result;
}
or when use C++0x conforming compiler You can use std::unique_ptr.
std::tr1::unique_ptr<int> myFunction() {
std::tr1::unique_ptr<int> result(new int(5));
return result;
}
The main difference is that:
shared_ptr allows multiple instances of shared_ptr pointing to the same RAW pointer. It uses reference counting mechanism to ensure that memory will not be freed as long as at least one instance of shared_ptr exist.
unique_ptr allows only one instance of it holding pointer but have true move semantic unlike auto_ptr.
For C++, in many cases, just return by value. Even in cases of larger objects, RVO will frequently avoid unnecessary copying.
Boost or TR1 shared pointers are generally the way to go. It avoids the copy overhead, and gives you semi-automatic deletion. So your function should look like:
boost::shared_ptr<int> myFunction2()
{
boost::shared_ptr<int> x = new int;
*x = 4;
return x;
}
The other option is just to allow a copy. That's not too bad if the object is small (like this one) or you can arrange to create the object in the return statement. The compiler will usually optimize a copy away if the object is created in the return statement.
For C++, you can use a smart pointer to enforce the ownership transfer. auto_ptr
or boost::shared_ptr
are good options.
One possibility is passing the function a pointer:
void computeFoo(int *dest) {
*dest = 4;
}
This is nice because you can use such a function with an automatic variable:
int foo;
computeFoo(&foo);
With this approach you also keep the memory management in the same part of the code, ie. you can’t miss a malloc just because it happens somewhere inside a function:
// Compare this:
int *foo = malloc(…);
computeFoo(foo);
free(foo);
// With the following:
int *foo = computeFoo();
free(foo);
In the second case it’s easier to forget the free as you don’t see the malloc. This is often at least partially solved by convention, eg: “If a function name starts with XY, it means that you own the data it returns.”
An interesting corner case of returning pointer to “function” variable is declaring the variable static:
int* computeFoo() {
static int foo = 4;
return &foo;
}
Of course this is evil for normal programming, but it might come handy some day.