0

在下面的代码中,drvdCls派生自bseCls. 此代码按原样编译和运行。然而,我在这里发现了一个问题:退出newBse后将被释放。Test()我对吗?

bseCls* Test()
{

    bseCls* newBse = new drvdCls();
    drvdCls newDrvd;
    newBse = &newDrvd;
    return newBse;

}
4

2 回答 2

4

最初指向的对象newBse将被泄露。当您将地址分配newDrvdnewBse您时,您将丢失指向堆分配对象的指针,您将无法获得delete它。在进程终止之前,该内存将无法使用。

此外,您将堆栈分配对象的地址作为指针返回,这有两个原因是不好的:

  1. 对象的析构函数将在函数返回之前被调用,这意味着您将使用指向被破坏对象的指针。
  2. 为对象分配的内存位于堆栈上,几乎肯定会被未来的函数调用破坏。那时,您的指针将指向不是 a 的东西bseCls,但您将像使用它一样使用它。

如果您使用此函数返回的指针,您将调用未定义的行为,并且您的程序有权执行任何操作。

于 2013-03-21T16:09:02.087 回答
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();
}

现在,当返回的对象超出范围时,分配的对象将自动为deleted 。unique_ptr

于 2013-03-21T16:09:12.863 回答