我继承了一些包含以下段落的代码:

TStringList* pPortList(NULL);
pPortList = FindCommPorts();
ConnectionDialog->PortList = pPortList;
int nModalReturn = ConnectionDialog->ShowModal();
delete pPortList;


FindCommPorts()是创建new TStringList(),填充并返回它的函数。

我很想用以下代码替换代码:

ConnectionDialog->PortList = FindCommPorts();
int nModalReturn = ConnectionDialog->ShowModal();


但是后来我意识到我对C ++的所有权语义还不够熟悉,无法确定这一点。是否会因为FindCommPorts()的结果从不delete d而泄漏内存?

编辑:再次查看代码,我不认为原始版本会导致指针悬垂-事实证明ConnectionDialog->PortList实际上是一个属性(我正在使用Borland C ++ Builder 6)。此属性具有一个自定义设置程序,该设置程序将字符串从TStringList中复制出来,此后不再使用传递的指针本身。我为没有提起这个而感到抱歉-代码的编写方式肯定看起来很糟糕。

最佳答案

如果从不delete d,则将泄漏内存。但是,此代码的问题更加严重。这样想你的情况:


FindCommPorts()返回一个指针
您告诉ConnectionDialog->PortList指向FindCommPorts()结果指向的相同内存。
然后,您在delete指向的内存中pPortList指向与ConnectionDialog->PortList指向的内存相同的对象!


此后,PortList变量指向已删除的内存,因此您不应访问它。如果您将需要再次使用此指针,则无论如何都不要删除它,因此您不必担心将FindCommPorts()的结果直接分配给ConnectionDialog->PortList。完成操作后,只需确保将其删除即可。

如果您需要该指针永远有效,那么这种情况就不会造成内存泄漏,因为需要数据。在这种情况下,程序终止时将释放内存。

编辑

阅读对您的问题的修改后,我认为您是正确的。您确实需要使用临时变量以防止内存泄漏。如果不执行此操作,则属性的设置器将复制FindCommPorts()返回的指针所指向的对象的副本,然后将保持分配的内存,但没有包含指向该指针的指针的变量。在这种情况下,您可以先创建临时变量,然后在分配后将其删除。

08-17 04:23