使用std :: vectors进行c ++内存泄漏

时间:2016-08-29 19:25:38

标签: c++ memory vector memory-leaks ram

我正在使用以下代码将400mb文件读入c ++向量:

#define RAMALLOC 20000000
struct worddata {
    std::string name;
    double ussage;
};
// ...
int counter = 0;
std::string dName;
double dUssage;
std::vector<worddata> primDataBank;
primDataBank.resize(RAMALLOC);
std::ifstream fIn(PATH + "output.dat");
while (fIn >> dName >> dUssage) {
    primDataBank[counter].name = dName;
    primDataBank[counter].ussage = dUssage;
    counter++;
}

我已将向量驻留到20,000,000项的大小,因此我在循环中分配它时,ram的使用不应该增加。但是当我运行它时,ram的使用会迅速增加。

在Visual Studio调试器堆快照中,它向我显示ram被processFrequencyData.exe!std::_Container_proxy占用。 “分配调用堆栈”看起来像这样:

enter image description here

这似乎源于载体。

如何阻止我的ram使用量增加?

感谢。

更新

当我在while循环中注释掉分配值

的代码行时,我的ram使用量仍然快速增加
while (fIn >> dName >> dUssage) {
    //primDataBank[counter].name = dName;
    //primDataBank[counter].ussage = dUssage;
    counter++;
}

但是当我也注释掉矢量代码时,ram的使用不会增加:

//std::vector<worddata> primDataBank;
//primDataBank.resize(RAMALLOC);

2 个答案:

答案 0 :(得分:1)

您的内存使用量增加,因为您正在创建和存储从文件中读取的所有字符串。

字符串不是固定大小的对象,因此为字符串预先分配空间的唯一方法是使用自定义分配器。

您应该更喜欢使用保留 emplace_back 而不是调整大小和设置字段,因为这样可以避免分配0个长度字符串。需要。

我觉得你的更新很难相信。

答案 1 :(得分:1)

您创建的矢量大致使用

20000000 * 32字节= 640 000 000即640 MB //谁说640K就足够了?

worddata的大小来自std :: string大约24个字节+ 8个双倍。

然后你开始读取字符串,如果它们足够小,字符串可能会使用小字符串优化,即使用内部数据和容量存储字符。 但如果它们大于~12(???)字符,则字符串会分配一个额外的数组来保留字符。

更新需要更多调查。