Return pointer to data declared in function - c++

I know this won’t work because the variable x gets destroyed when the function returns:
int* myFunction()
{
int x = 4;
return &x;
}
So how do I correctly return a pointer to something I create within the function, and what do I have to take care with? How do I avoid memory leaks?
I've also used malloc:
int* myFunction2()
{
int* x = (int*)malloc(sizeof int); *x = 4; return x;
}
How do you correctly do this - in C and C++?

For C++, you can use a smart pointer to enforce the ownership transfer. auto_ptr or boost::shared_ptr are good options.

Your second approach is correct. You just need to clearly document that the caller "owns" the result pointer, and is responsible for freeing it.
Because of this extra complexity, it is rare to do this for "small" types like int, though I'm assuming you just used an int here for the sake of an example.
Some people will also prefer to take a pointer to an already allocated object as a parameter, rather than allocating the object internally. This makes it clearer that the caller is responsible for deallocating the object (since they allocated it in the first place), but makes the call site a bit more verbose, so it's a trade-off.

For C++, in many cases, just return by value. Even in cases of larger objects, RVO will frequently avoid unnecessary copying.

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.

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.

In C++, you should use new:
int *myFunction()
{
int blah = 4;
return new int(blah);
}
And to get rid of it, use delete:
int main(void)
{
int *myInt = myFunction();
// do stuff
delete myInt;
}
Note that I'm invoking the copy constructor for int while using new, so that the value "4" is copied onto the heap memory. The only way to get a pointer to something on the stack reliably is to copy it onto the heap by invoking new properly.
EDIT: As noted in another answer, you will also need to document that the pointer needs to be freed by the caller later on. Otherwise you might have a memory leak.

There is another approach - declare x static. In this case it will be located in data segment, not on stack, therefore it is available (and persistent) during the program runtime.
int *myFunction(void)
{
static int x = 4;
return &x;
}
Please note that assignment x=4 will be performed only on first call of myFunction:
int *foo = myFunction(); // foo is 4
*foo = 10; // foo is 10
*foo = myFunction(); // foo is 10
NB! Using function-scope static variables isn't tread-safe technique.

Your second code snippet is correct.
To help avoid memory leaks, I let the coding conventions help me.
xxxCreate() will allocate memory for xxx and initialize it.
xxxDelete() will destroy/corrupt xxx and free it.
xxxInit() will initialize xxx (never allocate)
xxxDestroy() will destroy/corrupt xxx (never free)
Additionally, I try to add the code to delete/destroy/free as soon as I add the code to create/init/malloc. It's not perfect, but I find that it helps me differentiate between items that need to be freed and those that don't, as well as reducing the likelihood that I will forget to free something at a later time.

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.

I would try something like this:
int myFunction2b( int * px )
{
if( px )
{
*px = 4;
return 1;
}
// Choice 1: Assert or Report Error
// Choice 2: Allocate memory for x. Caller has to be written accordingly.
// My choice is 1
assert( 0 && "Argument is NULL pointer" );
return 0;
}

You're asking how to correctly return a pointer. That's the wrong question, because what you should be doing is using smart pointers rather than raw pointers. scoped_ptr and shared_ptr (available in boost and tr1) are good pointers to look at (e.g. here and here)
If you need the raw pointer for something (e.g. passing to a C function), the get() method will supply it.
If you must create raw pointers, e.g. for homework, then you can use malloc() (as you did) or new within a function, and hope you remember to de-allocate the memory (through free() and delete respectively) Or, in a slightly-less-likely-to-leak idiom, you can create the pointer with new, pass it to a function, and de-allocate with delete when you're done with it. Again, though, use smart pointers.

Related

In the case of using a std::unique_ptr to automatically deallocate memory upon exiting a scoped block, why not just use the stack?

This is a great answer about smart pointers, such as unique pointers: What is a smart pointer and when should I use one?.
Here is an example they provide as the simplest use of a unique pointer:
void f()
{
{
std::unique_ptr<MyObject> ptr(new MyObject(my_constructor_param));
ptr->DoSomethingUseful();
} // ptr goes out of scope --
// the MyObject is automatically destroyed.
// ptr->Oops(); // Compile error: "ptr" not defined
// since it is no longer in scope.
}
However, this begs the question: in cases such as this, where the goal is to simply delete the object (free the memory) the unique pointer points to when it goes out of scope, why not just put the whole object on the stack instead, like this??
void f()
{
{
MyObject myobj(my_constructor_param);
myobj.DoSomethingUseful();
} // myobj goes out of scope --
// and is automatically destroyed.
// myobj.Oops(); // Compile error: "myobj" not defined
// since it is no longer in scope.
}
It seems to me the only logic can be that some objects are so stinking large they may overflow the stack, as stacks seem to be limited to a few dozen KB to a few MB (C/C++ maximum stack size of program), whereas a heap can be hundreds of GB!
What's the logic? Give me some insight here into this seemingly unnecessary use case of the unique pointer. What am I missing?
Related:
"Another feature of the stack to keep in mind, is that there is a limit (varies with OS) on the size of variables that can be stored on the stack. This is not the case for variables allocated on the heap." (https://gribblelab.org/CBootCamp/7_Memory_Stack_vs_Heap.html)
While this is not a terrible useful example per-se, it becomes with some slight variations.
Polymorphism
struct Base { void blah() { std::cout << "Base\n";}};
struct Derived : Base { void blah() {std::cout << "Derived\n";}};
void blub(bool which) {
std::unique_ptr<Base> ptr = which ? new Base : new Derived;
ptr->blah();
}
Non-standard deleter
{
auto close = [] (FILE* fp) { fclose(fp);};
std::unique_ptr<FILE, decltype(close)> ptr(fopen("name"), close);
} // closes file
Dynamic Array (you can arguably use a vector)
{
std:: unique_ptr<int[]> ptr( new int [n]);
// From C++14 on, prefer if it is no problem to value-initialize the array
auto ptr = std::make_unique<int[]>(n);
// From C++20 on, there is no reason for the naked new
auto ptr = std::make_unique_for_overwrite<int[]>(n);
// is equivalent to the first line
}
EDIT: This also reasonable for big arrays, even if the size is know at compile time. If the size of the array would be really big (and this should be very, very rare) and you really do not want to run the risk of a stack overflow, this would be a safer possibility. But very probably std::vector is the better alternative still. Only if your object type is neither moveable nor copyable, the vector will have problems (since it cannot reallocate itself if necessary, and hence you can call basically no modifying member function).
Conditional creation of an object. (Only in C++11 and 14, after that use std::optional)
void blah (bool smth)
{
std::unique_ptr<T> opt;
if (smth) {
opt = std::unique_ptr<T>(new T);
}
}
If you want to return a pointer to an object, then without smart pointers, we had to do this:
MyClass* someFunc() {
MyClass* myObjPtr = new MyClass();
.
.
return myObjPtr;
}
void otherFunc() {
MyClass* myPtr = someFunc();
.
.
delete myPtr; // delete explicitely before return.
return;
}
Instead if we use smart pointers, we can do this:
typedef std::shared_ptr<MyClass> MyClassPtr;
MyClassPtr someFunc() {
MyClassPtr myObjPtr(new MyClass());
.
.
return myObjPtr;
}
void otherFunc() {
MyClassPtr myPtr = someFunc();
.
.
return; // when smart pointer goes out of scope,
// the heap allocated object which it contains is deallocated properly.
}
Size is not the primary concern, although it may be important if you have recursion, for example (I saw a library allocating 64 KiB buffer on stack, in a recursive function. But Musl provides 128 KiB stacks [to make threads lightweight], so...) But the object may be polymorphic, and not even created “right there” but rather returned from some function (as a pointer); unique_ptr may be handy to store that.
Besides that, unique_ptr (unlike auto_ptr AFAIK) is not restricted to on-stack usage. It can be a class member as well. Also it is not required to actually store anything, you may assign and reset it at any time.
Moreover, it is not restricted to C++ classes, you can store anything requiring cleanup there, like file descriptor or FILE*, for example.

Would there ever be a reason to initialize a pointer in a constructor with malloc?

As such:
class MyClass{
public:
int *property;
MyClass(){
property = (int*)malloc(sizeof(int));
}
~MyClass(){
free(property);
}
};
I understand that there are better ways to do this, but I don't think I understand why exactly this is incorrect.
Would there ever be a reason to initialize a pointer in a constructor with malloc?
At least couple of reasons comes to my mind:
you need to work with C code/library and pass pointer there that expected to be initialized by malloc()
You are limited with resources and want to be able to use realloc() with it
There could be more, but you need to be careful when working with raw pointers, either initialized by new or malloc(). For example your class violates rule of 3/5/0. Best way to handle that - use a smart pointer.
Also you need to remember that with malloc() you need to be sure that memory is properly initialized, it can be done with memset() or simple assignments with POD types or (and this is mandatory for non POD) through placement new. That usage is not trivial so you would want to deal with that when you really need it.
In general you should use new not malloc in c++ code. The only time not to do that is in extreme corner cases where you want to control exact location for some reason, building custom memory pools (and even then you should overload new so as not to call malloc directly in the class definition). In that case you use 'placement new'
The main reason to use new is that it will correctly construct the object that it just made. malloc will return garbage memory. Not relevant (maybe) for ints but certainly important for objects
You have to make sure to disable copy constructor/assignment operator which are generated by default in c++. If you don't, you will have undefined behavior. E.g. Below code will destruct twice.
#include<cstdlib>
static int number_of_constructions = 0;
static int number_of_destructions = 0;
struct S {
int * p;
S() {
p = (int*) malloc(sizeof(int));
number_of_constructions++;
}
~S() {
free(p);
number_of_destructions++;
}
};
void foo() {
S s;
S s2 = s;
}
Link: https://godbolt.org/g/imujg1

memory allocation by new

My first question is does the memory allocated by new in a function gets automatically deleted(deallocated) when the function ends.
int* foo()
{
int *a = new int; //memory allocated for an int
*a = 3;
return (a);
}//function ends -- is memory for integer still allocated.
If the memory is de-allocated automatically after the function ends, then shouldn't my next code give some error relating to accessing the memory which does not belong to me.
int main()
{
int *x = foo();
cout<<*x;
}
No it certainly does not. Every new has to be balanced with a delete. (And, to avoid any future doubt, any new[] has to be balanced with a delete[]).
There are constructs in C++ that will allow the effective release of memory once a container object has gone out of scope. Have a look at std::shared_ptr and std::unique_ptr.
No, the memory is not deallocated.
You should deallocate it manually with delete a;
In languages like Java or C# there is a so called Garbage Collector that handles memory deallocation when it finds out that some data is not longer needed. Garbage Collection can be used with C++, but it's not standard and in practice rarely used.
There are, however, other mechanisms you could use to automate deallocation of memory. Shared pointers are one of them. They introduce additional overhead. In regular C++ code usually the programmer is responsible for managing the memory (allocating and deallocating) manually. For beginners it's important to learn the basics before switching to more advanced mechanisms.
This is a bad practice to allocate dynamically from within a function and depend on the mercy of some other function to deallocate. Ideally, the caller should allocate space, pass that to the calling function and caller would deallocate when not in use.
void foo(int * a)
{
// a is pre-allocated by caller
*a = 3;
}//function ends -- caller takes care of allocation and deallocation
int main()
{
int *x = new int; // memory allocated for an int by caller
foo(x); // pass x as argument
cout << *x;
delete x; // deallocate, not required any more
return 0;
}
No, it is your responsibility to procure deallocation:
int *i = new int;
delete i;
However, the above code will sooner or later evolve into something that is almost impossible to make exception-safe. Better do not use pointers at all, or if you really must, use a smart pointer which will free the memory for you at the right moment:
std::shared_ptr<int> i (new int);
*i = 0xbeef;
return i;
There exist other smart pointers with different ownership semantics.
For most real world application, any imposed or assumed overhead introduced by smart pointers usually gets weight up easily against more expensive (I really mean money-saving) stuff like maintainability, extensibility, exception safety (where all there intermix into the other two).
Never forget that there exist alternatives to pointers, depending on the situation:
standard containers: If you need things like array
smart pointers: If you really need a pointer
references: Which you cannot forget to deallocate
plain objects: No pointers at all. Rely on copying and moving, which usually makes for a high degree of maintainability, extensibility, exception safety and performance. In C++, this should be your default choice.
As above, no raw pointers are never automatically deleted. This is why we don't use raw pointers for controlling lifetimes. We use smart pointers.
Here's your code snippet written correctly in modern c++:
std::unique_ptr<int> foo()
{
return std::unique_ptr<int>(new int(3));
// or std::make_unique<int>(3) for c++14
// function will either std::move the unique_ptr or emplace it efficiently
}
int main()
{
// x will either be created in-place or move-constructed by foo()
std::unique_ptr<int> x = foo();
// potential bug! pointers can be null
if (x) {
std::cout << *x;
}
else {
std::cout << "x is null\n";
}
}

*new is always wrong. ALWAYS

So as to explain about pointers and references in this question I wrote this code.
MyClass& MyClass::MyInstance()
{
static MyClass & myLocalVariable = * new MyClass(/*parameters*/);
return myLocalVariable ;
}
one of the comments, by a really impressive high reputation SO user, simply states:
*new is always wrong. ALWAYS.
It is the first time I'm told about this: Is it a famous coding standard we all should know about ? What are the reasons behind ?
I'm normally pragmatic, however this is too much even for me!
static MyClass & myLocalVariable = * new MyClass(/*parameters*/);
Seriously? Why not simply:
static MyClass myLocalVariable{/*parameters*/};
The most obvious reason is that if you don't keep a copy of the pointer which new returned, you're not likely to ever call delete on it.
On a more human level, it will make people reading your code think less of you, and that's never a good thing either.
I believe the stated user meant that allocating a static object using new is dangerous as the memory will most probably be leaked. Even more importantly your variable is not a pointer but a reference so the chance that you never free the memory returned by new is even greater(how often do you delete the address of a reference?).
THE problem is more than just useless allocations.
If nobody calls delete on it, it won't be deleted. Sure, the memory will be released when the program ends but its destructor doesn't get called.
Compare the output of using Get() and Get2() in the code below:
#include <iostream>
struct A
{
~A(){std::cout << "Deleted\n";}
};
A& Get()
{
static A & a = *new A;
return a;
}
A& Get2()
{
static A a;
return a;
}
int main()
{
//Case 1
Get();
//Case 2
Get2();
}
The output of this program is nothing when calling Get and Deleted when calling Get2.
In other words, resources with nontrivial destructors (commit-on-close file handle for example) will not be destroyed properly at program termination in case 1, but will in case 2.
The problem is that a raw new does not specify ownership. If I new up an object and return it, who owns it? Does the creating function/object own it, or does the calling function? If you return smart pointers (std::shared_ptr and std::unique_ptr) you are specifying ownership.
Not specifying ownership is one of the easiest ways to leak memory. I have the hardest time, even with professional programmers, getting people to understand ownership and work with it. This is mostly prevented by using good types (smart pointers) that specify ownership, just by existing.
type* function(); // Unspecified ownership.
// Must be well documented and all users must read
// and follow the documentation.
std::unique_ptr<type> function(); // Calling function owns returned pointer.
// Single ownership.
std::shared_ptr<type> function(); // Calling function owns returned pointer.
// Shared ownership. Can have multiple owners.
std::weak_ptr<type> function(); // Calling function references returned pointer.
// Must lock pointer to get owned object, if not deleted.
// Shared ownership. Can have multiple owners.
These different types of pointers express ownership just by existing unlike raw pointers.
As for new always being wrong. That is an overbroad generalization. std::shared_ptr is created using the global function std::make_shared. As of C++11 there is no std::make_unique, but that will be fixed in C++14. The only way to create a std::unique_ptr is to use new and immediately assign the pointer to a std::unique_ptr.
There are also places where you would want a raw pointer and to manually use new and delete, but they tend to be very low level and most programmers will rarely encounter them.
What really has me cringing about your code is not that you are using new but that you are dereferencing the pointer and assigning it to a reference. It would be almost impossible to guarantee that the destructor will ever be called. It also tends to leak memory, though in the case of assigning to a static variable it will be deallocated at program termination so you aren't really looking at memory leaking.
MyClass& MyClass::MyInstance()
{
static MyClass & myLocalVariable = * new MyClass(/*parameters*/);
return myLocalVariable ;
}
I would prefer to create to have the static variable be by value than by reference. This prevents putting the object on the heap. Depending on MyClass is could also allow the object to be mapped to memory from the executable without having to run any code to initialize it.
MyClass& MyClass::MyInstance()
{
static MyClass myLocalVariable(/*parameters*/);
return myLocalVariable ;
}

Returning a malloced pointer from a function , does it cause memory leak?

I have a function foo like
myType** foo(){
myType **array = malloc( .... );
//Do some stuff
return array;
}
Here I have malloced , but did not free it as I am returning it . Will this cause a memory leak ? Should I explicitly free it in the calling function after I use it ?
It's a memory leak only if you don't free the memory (regardless where).
In this case, you should free it after the function is called and you're done with the pointer.
But this is the C way of doing it. In C++ you'd return a smart pointer, and use new instead of malloc.
With this type of function, the caller is the "owner" of the resources pointed at by the pointer. So the caller has to either free the resources, or pass them on to someone else who will.
In C++ one would favour returning a type that manages its own resources, for example an std::vector, or a smart pointer, that both takes care of resource de-allocation and makes the ownership clear.
See this example,and don't worry, read all about copy elision, particularly named return value optimization (NRVO).
std::vector<std::vector<SomeType>> foo()
{
std::vector<std::vector<SomeType>> tmp = ....;
// do some stuff
return tmp;
}
Memory leaks are caused by not freeing memory. As long as the memory will get freed at some point, then it isn't leaked. But if the pointer ever gets "lost" or if some sort of dependency loop causes a situation where the memory stays around even after it is no longer useful, then at that point you've created a leak.
Usually in this type of situation, you create a pattern like this:
void* mything_init() {
void *obj = malloc(LEN);
// do some initialization
return obj;
}
void mything_uninit(void* thing) {
// any teardown
free(thing);
}
For every mything that you _init, you must eventually call _uninit on that object. That is your responsibility as the user of that library. While as the writer of that library, you make sure that anything you allocate in the _init gets properly freed in _uninit.
This is a C pattern rather than a C++ pattern as malloc() is a C idiom. C++ uses new and delete, and this sort of work us usually done in a constructor/destructor pair.
I had issues about this problem for long time. I suggest you to read this wiki page:
Smart Pointers
In your case you can use unique_ptr. So you would be able to transfer the ownership of the pointer to the caller function.
unique_ptr<int> callee1()
{
std::unique_ptr<int> p1(new int(5));
return p1;
}
int main()
{
std::unique_ptr<int> result = callee1() ;
(*result)++; // Increase the value stored in the pointer
std::cout << "New Value: " << (*result) << std::endl;
result.reset() ;
}
Hope this code sniper helps you.