我继承了一些包含以下段落的代码:
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()
返回的指针所指向的对象的副本,然后将保持分配的内存,但没有包含指向该指针的指针的变量。在这种情况下,您可以先创建临时变量,然后在分配后将其删除。