2013-01-09 79 views
0

我正在製作一箇中級/高級C++程序,一個視頻遊戲。如何正確存儲多個實例對象?

最近我一直注意到有很多內存被泄漏,我想知道如果我創建我的實例的方式可能有問題。

下面是一個總結(但原本複雜)類:

class theObject 
{ 
//Instance variables 
//Instance functions 
}; 

有了這個對象(與我存儲任何其他的目的,我的theObject每一個不同的變異模板的數組索引。部分並不重要,但我將它們存儲(或者在我看來)的方式是:

//NEWER VERSION WITH MORE INFO 
void spawnTheObject() 
{ 
theObject* NewObj=ObjectArray[N]; 
//I give the specific copy its individual parameters(such as its spawn location and few edited stats) 
NewObj->giveCustomStats(int,int,int,int);//hard-coded, not actual params 
NewObj->Spawn(float,float,float); 
myStorage.push_back(new theObject(*NewObj)); 
} 


//OLDER VERSION 
void spawnTheObject() 
    { 
    //create a copy of the arrayed object 
    theObject* NewObj=new theObject(*ObjectArray[N]); 
    //spawn the object(in this case it could be a monster), and I am spawning multiple copies of them obviously 
    //then store into the storage object(currently a deque(originally a vector)) 
    myStorage.push_back(new theObject(*NewObj)); 
    //and delete the temporary one 
    delete NewObj; 
    } 

我目前使用雙端隊列(最近從使用媒介改變),但我看到在內存中沒有差異用法。我雖然從「評論中發現了測試「這些產卵函數是我的內存泄漏的原因。由於這是創建/產生實例的錯誤方式,我想知道是否有更好的方法來存儲這些對象。

tl; dr:什麼是一些更好的對象來存儲非恆定數量的對象,以及如何?

+4

使用智能指針並忘記內存泄漏。 – ForEveR

+0

「當你需要一個(非平凡的)拷貝構造函數,拷貝賦值操作符或析構函數時,你很可能也需要實現其他的」 – 9dan

+0

「@ 9dan指的是[三條規則]( http://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29)。 –

回答

2

我猜你永遠不會清除myStorage中導致內存增加的新產生對象(當你引用內存泄漏時)。如果我是正確的myStorage的聲明如下:

std::deque<theObject*> myStorage; 

如果調用下面任一呼叫,指向theObject是刪除,但真正的動態分配的對象不會被刪除。

myStorage.pop_back(); 
myStorage.clear(); 

另一個小問題在你的代碼,你這是不必要的對象spawnTheObject()功能分配/ dellocate。

如何清潔與指針類型的容器

你需要通過myStorage每個元素進行迭代,刪除的對象然後清除容器,例如:

for (std::deque<theObject*>::iterator iter=myStorage.begin(); 
    iter != myStorage.end(); ++iter) 
{ 
    delete (*iter); 
} 
myStorage.clear(); 

更好的解決方案:

使用智能指針std::dequestd::vector,然後當您從ST中刪除一個元素L容器指針指向的對象也會自動刪除。

#include <memory> 

std::deque<std::shared_ptr<theObject> > myStorage; 
myStorage.push_back(std::shared_ptr<theObject>(new *ObjectArray[N])); 

mySorage.clear(); // all memories cleared properly, no worries 
+0

好吧,我真的不明白爲什麼我不斷地收到錯誤:'shared_ptr不是std'的成員。我爲這個項目增加了內存,我甚至將它添加到了單個文件中。 – Molma

+0

好吧,我發現自從我使用Gcc以來,我不得不使用'' – Molma

+0

是的,如果你的gcc不是最新版本的話。 shared_ptr在tr1下(技術報告1)。它也位於std :: tr1名稱空間下。 – billz

0

如果您在遊戲結束時沒有手動從myStorage中刪除對象,或者需要銷燬對象,則會導致內存泄漏。

myStorage.push_back(new theObject(*NewObj)); 

被推入存儲器的對象是由您分配的,所以它在您需要消失時應該被銷燬。

另外我不明白需要中間NewObj對象,它不是一個內存泄漏,但它是一個不必要的性能成本,1分配/釋放+ 1副本。

永遠提到,你最好的選擇是開始使用智能指針,即std::unique_ptrstd::shared_ptr(僅當C++ 11)。

+0

等等,所以我應該只使用'shared_ptr'作爲deque嗎?或者對於我創建的每個實例? – Molma

+0

deque應該是'std :: deque >' –

+0

爲什麼不是'deque '?從他的代碼示例中可以明顯看出@Molma很高興能夠複製'theObject'實例並且不需要多態克隆,因此動態分配和智能指針是不必要的複雜因素。 –

相關問題