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.
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;
}
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 d1
and d2
will be deallocated, because they are both on the stack. What is not deallocated is the Data
object you allocated in your getData()
function. You can see this a little more clearly if you flesh out your Data
class with instrumentation in the constructors and destructor. For example:
class Data {
public:
Data() { cout << "Data default ctor" << endl; }
Data(const Data& other) { cout << "Data copy ctor" << endl; }
~Data() { cout << "Data dtor" << endl; }
static Data& getData()
{
Data *i = new Data();
return *i;
}
};
Note that I have explicitly declared the copy constructor for Data
. In your example you are implicitly calling that constructor when you do Data d1 = getData();
, and I suspect this is where your confusion is coming from. Now if I run this simple program:
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
Data d1 = Data::getData();
Data d2;
return 0;
}
The output is as follows:
Data default ctor
Data copy ctor
Data default ctor
Data dtor
Data dtor
Line-by-line, here's what you're seeing:
Data
in getData()
.d1
from the dynamically allocated Data
you just made.d2
.d2
when it goes out of scope at the end of main()
.d1
when it goes out of scope at the end of main()
.Note that there are three constructor calls, but only two destructor calls -- indicating that you have leaked exactly one Data
object.
Hope that helps,
Eric Melski
d1
is a stack object, copy-constructed from the reference returned from getData()
. d1
is freed, but the object created in getData()
is leaked.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With