我正在使用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)。如果我在delete语句之后为*它分配NULL,它们都是NULL。所以我真的没有理由为什么这会给我内存泄漏。
有人有想法吗?谢谢!
答案 0 :(得分:5)
continue
语句导致至少一次泄漏。循环的开始分配一个新的Setting
值并继续离开循环体而不释放内存。您需要删除它以防止泄漏。
Setting* s = new Setting;
getline(file, line);
if(line.empty()) {
delete s;
continue;
}
总的来说,虽然你在这里玩手动内存管理,但很容易出错。我强烈建议您考虑使用shared_ptr<Setting>
类型而不是原始Setting*
类型。它将使您的代码更加健壮
答案 1 :(得分:0)
移动
Setting* s = new Setting;
在继续循环之后,将解决您的问题。
编辑:
我会更详细地解释一下。您正在为每一行创建一个新的设置对象,即使是空行也是如此。但是,只有非空行的设置对象存储在容器中,我假设您稍后用它来释放内存。
通过在评估空行的语句之后放置创建设置对象的代码,您应该解决此问题。