2013-03-28 126 views
2

我正在使用VLD來檢測我正在用C++編寫的遊戲中的內存泄漏。它直到最近才報告沒有泄漏。我有一個SettingsManager類(所有靜態方法)加載設置並可以保存它們(文件I/O)。以下是我會的「鍵=值」設置的列表加載到一個載體:爲什麼我有內存泄漏?

std::vector<Setting*> settings; 
SettingsManager::loadFromFile(settingsLocation + "display" + settingsExtension, settings); 

這個載體填寫正確,我可以進一步處理數據。

std::ifstream file; 
file.open(filename); 
if(file.is_open()) 
{ 
    std::string line; 
    unsigned pos; 
    while(file.good()) 
    { 
     Setting* s = new Setting; 
     getline(file, line); 
     if(line.empty()) 
     { 
      // do not read empty lines 
      continue; 
     } 
     // parse to Setting 
     pos = line.find('='); 
     s->key = line.substr(0, pos); 
     s->value = line.substr(pos + 1); 
     // add to vector 
     settings.push_back(s); 
    } 
    file.close(); 
    return true; 
} 
else 
{ 
    return false; 
} 

所以,這個分配設置(這是一個簡單的結構具有兩個的std :: string變量):在loadFromFile()方法被執行如下。

SettingsManager::deleteSettings(settings); 

其被實現如下::

​​

當調試時,deleteSettings後呼叫在向量的所有元素我從那裏我調用loadFromFile方法用下面的方法調用刪除它們是壞Ptr的(Visual Studio 2010 Express)。如果我在刪除語句之後給它分配NULL,它們都是NULL。所以我真的沒有理由爲什麼這會給我內存泄漏。

任何人有想法?謝謝!

+0

使用'std :: unique_ptr',這個問題神奇地修復了它自己,或者變成了一個編譯器錯誤,它可以幫助你手動修復它。 –

+0

我們可能需要查看類「Settings」的頭部以及其析構函數的代碼。 – jdehaan

+1

我不知道答案,這可能是誤報。但是你可以做一件簡單的事情。不要使用指針!如果你只是'std :: vector '而不是'std :: vector '那麼肯定不會有任何泄漏。我看不出有什麼好的理由來使用指針。 – john

回答

5

continue聲明造成至少一次泄漏。循環的開始會分配一個新的值,並繼續保留循環體而不釋放內存。您需要將其刪除以防止泄漏。

Setting* s = new Setting; 
getline(file, line); 
if(line.empty()) { 
    delete s; 
    continue; 
} 

總的來說,雖然你在這裏玩手動內存管理,很容易出錯。我強烈建議你考慮使用類似shared_ptr<Setting>而不是原始Setting*。它會使你的代碼更健壯

+0

感謝您的快速回答! shared_ptr是來自標準C++還是來自庫(如Boost)的東西? – RaptorDotCpp

+0

@RaptorDotCpp我相信'shared_ptr'起源於boost,但現在是C++的一部分11 – JaredPar

+0

好吧,我一定會檢查出 – RaptorDotCpp

0

移動

Setting* s = new Setting; 

到後繼續循環,將解決你的問題。

編輯:

我會更詳細地解釋。您正在爲每一行創建一個新的設置對象,即使是空行。但是,只有非空行的設置對象存儲在容器中,我假設您稍後使用它來釋放內存。

通過在評估空行的語句之後放置創建設置對象的代碼,您應該修復此問題。

+0

有道理,謝謝! – RaptorDotCpp

相關問題