2011-09-08 108 views
0

我在使用Qt(C++)编写的应用程序中有内存泄漏。我怀疑问题在于这条线。QVector :: replace()是否创建深层副本?

for(int i=0; i<DATA_LENGTH;i++){ 
     cdata1->replace(i,data->at(i));  
} 

cdata1是QVector,数据是的QList

我使用replace()的原因是,我有恒定的数据长度。而且我不想每次都创建一个QVector。 QVector初始化与该行的对象构造:

cdata1 = new QVector<double>(DATA_LENGTH,0); 

Qt文档说

注意,使用非const运营商可能会导致QVector做一次深层 副本。

我问的是replace()函数会导致深层复制,或者我怎么理解?

+0

'data'包含什么? –

+0

数据也在custtroctor中初始化为: data = new QList (); 它用data.append()填充双打; – HeyYO

+0

我没有在这里看到泄漏,你按照价值复制了双层,没有泄漏。 –

回答

2

深度复制意味着整个容器,而不是元素。正如在您引用的句子后面链接的那样,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. 

这也是为什么在堆上创建容器的理由很荒谬(和unidiomatic)几乎所有的情况下,你应该在堆栈上创建它们。

0

是的,它复制你的双值。但我不认为双重值可能会受到内存泄漏,除非你用new创建它们?

不管怎么说,依赖于你周围的代码你也许可以通过使用

cdata1 = data->toVector(); 

替换整个块(参见http://doc.qt.nokia.com/latest/qlist.html#toVector

作为一个额外的暗示,你就应该开始使用更可读的变量名比cdata1data。您的变量应描述他们正在存储的内容,例如如果你有一个存储温度数据点的列表,它应该被称为像温度数据点或温度数据点列表。它当然涉及更多的输入,而不是“数据”,但如果你在一年左右的时间内查看你的代码,你将不会后悔使用更多可读的名字。

+0

其实我试图在写这里时简化名称,而且我只需要* * data **。这就是为什么我没有使用** toVector()**。 – HeyYO

+0

嗯,您可以使用'data-> mid(0,DATA_LENGTH)'来检索列表的第一个DATA_LENGTH元素,并将其转换为如果你仍然需要一个向量, –

+0

哦,谢谢你!我想我错过了,因为它的名字,我正在寻找像“复制/切片等”的东西。 – HeyYO