I’m 99% certain the answer to this is a blinding no. Please validate my proposition that the following code will produce a memory leak.
Data &getData() { Data *i = new Data(); return *i; } void exampleFunc() { Data d1 = getData(); Data d2; /* d1 is not deallocated because it is on the heap, and d2 is * because it is on the stack. */ }
Please note that this is an oversimplified example, so clearly you wouldn’t actually use the above code… So no need to point this out thanks.
Update 1:
To add to this, what if I assign the pointer to a reference? In this case, I assume that the data is not copied…
Data &getData() { Data *i = new Data(); return *i; } void exampleFunc() { // Does copying occur here? Data &d1 = getData(); // Does this deallocate the memory assigned to the pointer? delete &d; }
Update 2:
I guess to answer my own question (in update 1) the following code proves that assigning a reference to a reference does not cause a copy…
#include <iostream> #include <string> using namespace std; class Data { public: string mName; Data(const string &name) : mName(name) { cout << mName << ' default ctor' << endl; } Data(const Data& other) { mName = other.mName + ' (copy)'; cout << mName << ' copy ctor' << endl; } ~Data() { cout << mName << ' dtor' << endl; } static Data &getData(const string &name) { Data *d = new Data(name); return *d; } }; int main() { cout << 'd1...' << endl; Data d1 = Data::getData('d1'); cout << 'd2...' << endl; Data d2('d2'); cout << 'd3...' << endl; Data &d3 = Data::getData('d3'); cout << 'return...' << endl; return 0; }
Yields the following result…
d1... d1 default ctor d1 (copy) copy ctor d2... d2 default ctor d3... d3 default ctor return... d2 dtor d1 (copy) dtor
Thanks to Eric Melski for a great answer (my code in update 2 is a modified copy of his exmaple code).
Actually both
d1andd2will be deallocated, because they are both on the stack. What is not deallocated is theDataobject you allocated in yourgetData()function. You can see this a little more clearly if you flesh out yourDataclass with instrumentation in the constructors and destructor. For example:Note that I have explicitly declared the copy constructor for
Data. In your example you are implicitly calling that constructor when you doData d1 = getData();, and I suspect this is where your confusion is coming from. Now if I run this simple program:The output is as follows:
Line-by-line, here’s what you’re seeing:
DataingetData().d1from the dynamically allocatedDatayou just made.d2.d2when it goes out of scope at the end ofmain().d1when it goes out of scope at the end ofmain().Note that there are three constructor calls, but only two destructor calls — indicating that you have leaked exactly one
Dataobject.