QVector::replace() 是不是创建深层副本?
Posted
技术标签:
【中文标题】QVector::replace() 是不是创建深层副本?【英文标题】:Does QVector::replace() create a deep copy?QVector::replace() 是否创建深层副本? 【发布时间】:2011-09-08 09:37:09 【问题描述】:我使用 Qt (C++) 编写的应用程序中有内存泄漏。我怀疑问题出在那条线上。
for(int i=0; i<DATA_LENGTH;i++)
cdata1->replace(i,data->at(i));
cdata1 是一个 QVector,data 是一个 QList 。
我使用 replace() 的原因是,我有恒定长度的数据。而且我不想每次都创建一个 QVector。 QVector 在对象构造函数上用该行初始化:
cdata1 = new QVector<double>(DATA_LENGTH,0);
Qt 文档说
请注意,使用非常量运算符会导致 QVector 进行深度处理 复制。
我要问的是 replace() 函数是否会导致深层复制,或者我该如何理解?
【问题讨论】:
数据也在 cunstroctor 中初始化为: data = new QListcdata1->
,这表明 cdata1 是一个指针。这可以解释内存泄漏。我不赞成这个问题,因为提供不完整和误导性的信息不是提出问题的好方法。
抱歉,我没想到 :( 。无论如何感谢您的解决方案。但我仍然想知道为什么使用指针会导致这种情况?
【参考方案1】:
深拷贝是指整个容器,而不是元素。正如您引用的句子之后链接的那样,QVector 使用implicit sharing,也称为写时复制。容器的只读副本很便宜,因为内部是共享的,直到其中一个副本被修改:
QVector<A> vec1;
...
QVector<A> vec2 = vec1; //cheap, only copies a pointer internally. vec1 and vec2
int siz2 = vec2.size(); //cheap, doesn't modify vec2, vec1 and vec2 are still the same object, internally
vec2[0] = something; //potentially expensive: modifies vec2, thus vec2 "detaches" from vec1, getting its own copy of vec1's internal data, which is then modified by the assignment.
这也是为什么在堆上创建容器在几乎所有情况下都相当荒谬(且不合时宜)的原因,您应该改为在堆栈上创建它们。
【讨论】:
【参考方案2】:是的,它复制了你的双精度值。但是我不认为 double 值会受到内存泄漏的影响,除非您使用 new
创建它们?
无论如何,根据您周围的代码,您可以使用替换整个块
cdata1 = data->toVector();
(见http://doc.qt.nokia.com/latest/qlist.html#toVector)
作为附加提示,您应该开始使用比cdata1
或data
更具可读性的变量名称。您的变量应该描述它们存储的内容,例如如果您有一个存储温度数据点的列表,则应将其称为 temperatureDataPoints 或 temperatureDataPointList。当然,它涉及比“数据”更多的输入,但如果您在一年左右查看您的代码,您不会后悔使用更具可读性的名称。
【讨论】:
其实我在这里写的时候试图简化名字。我只需要 data 的一部分。这就是我不使用 toVector() 的原因。 嗯,您可以使用data->mid( 0, DATA_LENGTH )
检索列表的第一个 DATA_LENGTH 元素,如果仍然需要将其转换为向量。
哦,谢谢!我想我错过了因为它的名字。我正在寻找诸如“复制/切片等”之类的东西..以上是关于QVector::replace() 是不是创建深层副本?的主要内容,如果未能解决你的问题,请参考以下文章