0

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

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

FindCommPorts()是一个创建 a new TStringList()、填充它并返回它的函数。

我很想用这个替换代码:

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

但后来我意识到我对 C++ 的所有权语义不够熟悉,无法确定这一点。会不会因为FindCommPorts()is never deleted的结果而导致内存泄漏?

编辑:再次查看代码,我认为原始版本不会导致悬挂指针——事实证明这ConnectionDialog->PortList实际上是一个属性(我使用的是 Borland C++Builder 6)。该属性有一个自定义设置器,用于将字符串从 中复制出来,TStringList之后不再使用传递的指针本身。对于之前没有提到这一点,我深表歉意——代码的编写方式确实看起来很糟糕。

4

1 回答 1

1

如果它从不deleted,那么是的,你会泄漏内存。但是,您在使用此代码时遇到的问题更严重。想想你的情况是这样的:

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

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

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

编辑

阅读对您问题的编辑后,我认为您是对的。您确实需要临时变量以防止内存泄漏。如果你不这样做,属性的设置器将复制由返回的指针指向的对象FindCommPorts(),然后内存将保持分配状态,但没有包含指向它的指针的变量。在这种情况下,您可以制作临时变量,然后在完成赋值后将其删除。

于 2013-06-20T19:23:39.020 回答