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 QList();它充满了双打 data.append(); 我没有看到这里有泄漏,你是按值复制双精度的,没有泄漏。 我使用了纯 c++ 数组而不是 QVector。我已经写了而不是上面的代码: for(int i=0; iat(i);现在我的问题解决了。所以我相信我的问题在于 QVector::replace().. -1 您声明“cdata1 是一个 QVector”,但是您正在执行 cdata1-&gt;,这表明 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)

作为附加提示,您应该开始使用比cdata1data 更具可读性的变量名称。您的变量应该描述它们存储的内容,例如如果您有一个存储温度数据点的列表,则应将其称为 temperatureDataPoints 或 temperatureDataPointList。当然,它涉及比“数据”更多的输入,但如果您在一年左右查看您的代码,您不会后悔使用更具可读性的名称。

【讨论】:

其实我在这里写的时候试图简化名字。我只需要 data 的一部分。这就是我不使用 toV​​ector() 的原因。 嗯,您可以使用 data-&gt;mid( 0, DATA_LENGTH ) 检索列表的第一个 DATA_LENGTH 元素,如果仍然需要将其转换为向量。 哦,谢谢!我想我错过了因为它的名字。我正在寻找诸如“复制/切片等”之类的东西..

以上是关于QVector::replace() 是不是创建深层副本?的主要内容,如果未能解决你的问题,请参考以下文章

原型模式(浅克隆和深克隆)

变量赋值浅拷贝深拷贝

切片操作会给我一个深拷贝还是浅拷贝?

浅拷贝和深拷贝

深拷贝与浅拷贝

深拷贝与浅拷贝