2

C++ で作成しているゲームで、VLD を使用してメモリ リークを検出しています。ごく最近まで、漏れはまったく報告されていませんでした。設定をロードして保存できる SettingsManager クラス (すべての静的メソッド) があります (ファイル I/O)。「キー=値」設定のリストをベクターにロードする方法は次のとおりです。

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

このベクトルは正しく入力されており、データをさらに処理できます。loadFromFile() メソッドは次のように実装されます。

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;
}

したがって、これは Settings (2 つの std::string 変数を持つ単純な構造体) を割り当てます。次のメソッド呼び出しで loadFromFile メソッドを呼び出した場所からそれらを削除します。

SettingsManager::deleteSettings(settings);

これは次のように実装されます。

void SettingsManager::deleteSettings(std::vector<Setting*>& settings)
{
    for(std::vector<Setting*>::iterator it = settings.begin(); it != settings.end(); ++it)
    {
            delete (*it);
    }
}

デバッグすると、deleteSettings 呼び出しの後、ベクター内のすべての要素が Bad Ptr (Visual Studio 2010 Express) になります。delete ステートメントの後に *it に NULL を割り当てると、それらはすべて NULL になります。したがって、これがメモリリークを引き起こしている理由は本当にわかりません。

誰にもアイデアがありますか?ありがとう!

4

2 に答える 2

5

このcontinueステートメントは、少なくとも 1 つのリークを引き起こしています。ループの開始時に新しい値が割り当てられ、Settingcontinue はメモリを解放せずにループ本体を終了します。漏れを防ぐために削除する必要があります。

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

全体として、ここでは手動のメモリ管理で遊んでいますが、間違いやすいです。shared_ptr<Setting>raw の代わりにlike 型を使用することを検討することを強くお勧めしますSetting*。コードをより堅牢にします

于 2013-03-28T21:28:17.183 に答える
0

動く

Setting* s = new Setting;

問題を解決する継続ループの後に。

編集:

詳しく説明します。現在、空の行であっても、すべての行に対して新しい設定オブジェクトを作成しています。ただし、空でない行の設定オブジェクトのみがコンテナーに保存されます。これは、後でメモリを解放するために使用すると想定しています。

空行を評価するステートメントの後に設定オブジェクトを作成するコードを配置することで、この問題を解決する必要があります。

于 2013-03-28T21:35:18.927 に答える