2011-09-08 157 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