Nic*_*ton 5 c++ memory-management
我99%肯定的答案,这是一个致盲没有.请验证我的命题,即以下代码将产生内存泄漏.
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. */
}
Run Code Online (Sandbox Code Playgroud)
请注意,这是一个过于简单的例子,所以显然你不会真正使用上面的代码...所以不需要指出这一点谢谢.
要添加到此,如果我将指针指定给引用怎么办?在这种情况下,我假设数据没有复制......
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;
}
Run Code Online (Sandbox Code Playgroud)
我想回答我自己的问题(在更新1中)以下代码证明分配对引用的引用不会导致副本...
#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;
}
Run Code Online (Sandbox Code Playgroud)
产生以下结果......
d1...
d1 default ctor
d1 (copy) copy ctor
d2...
d2 default ctor
d3...
d3 default ctor
return...
d2 dtor
d1 (copy) dtor
Run Code Online (Sandbox Code Playgroud)
感谢Eric Melski给出了一个很好的答案(我在更新2中的代码是他的exmaple代码的修改后的副本).
Eri*_*ski 24
实际上,这两个d1和d2将被释放,因为它们都是在栈上.未释放的是Data您在getData()函数中分配的对象.如果你Data在构造函数和析构函数中使用仪器充实你的类,你可以更清楚地看到这一点.例如:
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;
}
};
Run Code Online (Sandbox Code Playgroud)
请注意,我已明确声明了复制构造函数Data.在您的示例中,当您这样做时,您隐式调用该构造函数Data d1 = getData();,并且我怀疑这是您的混淆来自哪里.现在,如果我运行这个简单的程序:
#include <iostream>
using namespace std;
int main(int argc, char *argv[])
{
Data d1 = Data::getData();
Data d2;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出如下:
Data default ctor
Data copy ctor
Data default ctor
Data dtor
Data dtor
Run Code Online (Sandbox Code Playgroud)
逐行,这是你所看到的:
Data在getData().d1从Data刚刚创建的动态分配创建.d2.d2在结束时超出范围时被调用main().d1在结束时超出范围时被调用main().请注意,有三个构造函数调用,但只有两个析构函数调用 - 表示您只泄漏了一个Data对象.
希望有所帮助,
埃里克·梅尔斯基