2

我正在使用 VLD 来检测我用 C++ 编写的游戏中的内存泄漏。它直到最近才报告没有泄漏。我有一个 SettingsManager 类(所有静态方法),它加载设置并可以保存它们(文件 I/O)。这是我将“key = value”设置列表加载到向量中的方法:

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(这是一个带有两个 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)。如果我在删除语句之后将 NULL 分配给 *it,它们都是 NULL。所以我真的看不出为什么这会给我带来内存泄漏。

有人有想法吗?谢谢!

4

2 回答 2

5

continue声明导致至少一次泄漏。循环的开始分配一个新Setting值并继续离开循环体而不释放内存。您需要删除它以防止泄漏。

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

总的来说,尽管您在这里使用手动内存管理,但很容易出错。我强烈建议您考虑使用 likeshared_ptr<Setting>而不是 raw类型Setting*。它将使您的代码更加健壮

于 2013-03-28T21:28:17.183 回答
0

移动

Setting* s = new Setting;

在将解决您的问题的继续循环之后。

编辑:

我会更详细地解释。您当前正在为每一行甚至是空行创建一个新的设置对象。但是,只有非空行的设置对象存储在您的容器中,我假设您稍后会使用它来释放内存。

通过将创建设置对象的代码放在评估空行的语句之后,您应该可以解决此问题。

于 2013-03-28T21:35:18.927 回答