我需要为这个赋值使用一个临时值吗?
Do I need to use a temporary value for this assignment?
我继承了一些包含以下段落的代码:
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
的字符串复制出来,并且传递的指针本身之后不使用。我很抱歉之前没有提到这一点——代码的编写方式,它确实看起来很糟糕。
如果它从来没有 delete
d,那么是的,您将泄漏内存。然而,这段代码的问题甚至更糟。想像一下你的处境:
- 告诉
ConnectionDialog->PortList
指向FindCommPorts()
结果指向的相同内存。 - 然后
delete
在pPortList
指向的内存中的对象,与ConnectionDialog->PortList
指向的内存相同!
FindCommPorts()
返回一个指针之后,PortList
变量指向已删除的内存,您不应该访问它。如果你需要再次使用这个指针,你不应该删除它,所以你不必担心将FindCommPorts()
的结果直接赋值给ConnectionDialog->PortList
。当你用完它的时候,一定要把它删除。
如果您需要该指针永远有效,那么这种情况不是内存泄漏,因为需要数据。在这种情况下,当程序终止时,内存将被释放。
编辑
看了你问题的编辑后,我知道你是对的。您确实需要临时变量来防止内存泄漏。如果不这样做,属性的setter将复制FindCommPorts()
返回的指针所指向的对象,然后内存将保持分配,但不包含指向它的指针的变量。在这种情况下,您创建临时变量,然后在完成赋值后删除它是正确的。
- 为什么我必须在C++中添加一个赋值符号来声明一个数组
- cin >> int 给定一个字符串将 int 赋值为 0
- 复制赋值函数如何访问另一个对象的私有成员(Stroustroup 原则和实践书)?
- c++问题:给一个变量赋值后,另一个变量发生了变化
- 链表指针赋值为什么我们不能直接将尾巴分配给 temp 而不是尾巴>尾巴下一个
- 创建一个类并在C++中使用构造函数(赋值)
- 是否有必要重载具有另一个类 B 的数据成员的类 A 的赋值运算符和复制构造函数?
- 有没有办法通过从另一个文件中读取值来为宏赋值
- 在一个语句中对原子布尔变量进行多次赋值
- vector.back() 可以用来为向量的最后一个元素赋值吗?
- 为什么同时使用一个赋值运算符处理复制和移动赋值效率不高
- 在一个线程内进行的赋值在另一个线程中不可见
- 创建一个可以通过赋值初始化但不可复制的类型
- 如何使用const_reference类型来声明一个变量并为其赋值 front() 函数的返回值
- 从字符串数组打印其中一个字符串时出现空指针赋值错误
- C++返回一个数组并将其赋值给一个变量
- 正在初始化一个真正初始化的垃圾变量,或者只是一个赋值
- 在c++中创建一个赋值对象
- 输出一个赋值给c++双精度数组元素的字符串
- 为什么函数中变量的最后一个赋值不能被视为移动?