我需要为这个赋值使用一个临时值吗?

Do I need to use a temporary value for this assignment?

本文关键字:一个 赋值      更新时间:2023-10-16

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

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?

Edit:再次查看代码,我不认为原始版本导致挂起指针-事实证明ConnectionDialog->PortList实际上是一个属性(我使用Borland c++ Builder 6)。该属性有一个自定义setter,将TStringList的字符串复制出来,并且传递的指针本身之后不使用。我很抱歉之前没有提到这一点——代码的编写方式,它确实看起来很糟糕。

如果它从来没有 deleted,那么是的,您将泄漏内存。然而,这段代码的问题甚至更糟。想像一下你的处境:

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

之后,PortList变量指向已删除的内存,您不应该访问它。如果你需要再次使用这个指针,你不应该删除它,所以你不必担心将FindCommPorts()的结果直接赋值给ConnectionDialog->PortList。当你用完它的时候,一定要把它删除。

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

编辑

看了你问题的编辑后,我知道你是对的。您确实需要临时变量来防止内存泄漏。如果不这样做,属性的setter将复制FindCommPorts()返回的指针所指向的对象,然后内存将保持分配,但不包含指向它的指针的变量。在这种情况下,您创建临时变量,然后在完成赋值后删除它是正确的。