在下面的代码中,drvdCls
来自bseCls
。此代码按原样编译和运行。但是我在这里发现了一个问题:newBse
退出Test()
后会被取消分配。我是对的吗?
bseCls* Test()
{
bseCls* newBse = new drvdCls();
drvdCls newDrvd;
newBse = &newDrvd;
return newBse;
}
答案 0 :(得分:4)
newBse
最初指向的对象将被泄露。当您将newDrvd
的地址分配给newBse
时,您将丢失指向堆分配对象的指针,并且您将无法delete
它。在进程终止之前,此内存将无法使用。
此外,您将堆栈分配的对象的地址作为指针返回,这有两个原因:
bseCls
的内容,但您将像使用它一样使用它。如果您使用此函数返回的指针,则表示您正在调用未定义的行为,并且您的程序具有执行任何的许可。
答案 1 :(得分:1)
不,它不会自动解除分配。必须通过拨打new
来匹配对delete
的每次通话。但这不是你的代码唯一的问题,你也从函数返回局部变量的地址。
newBse = &newDrvd; // memory leak, pointer to previously allocated object is lost
return newBse; // newDrvd is destroyed when function exits, so returned
// pointer points to invalid memory
您可能想要做的是
bseCls* Test()
{
return new drvdCls();
}
现在调用者在使用后必须在返回的指针上调用delete
。你应该做的是
std::unique_ptr<bseCls> Test()
{
return new drvdCls();
}
现在,当返回的delete
超出范围时,分配的对象将自动为unique_ptr
。
答案 2 :(得分:0)
您有两个危险的缺陷
drvdCls newDrvd;
在堆栈上声明一个本地对象,从函数返回后,它将被销毁。然后,指向newBse
的{{1}}将无效。
将newDrvd
分配给&newDrvd
后内存泄漏。
让我们仔细看看:
newBse