2013-03-28 125 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

相关问题