std::vectors 的 c++ 内存泄漏
c++ memory leak with std::vectors
我正在使用以下代码将 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
占用。 "allocation call stack" 看起来像这样:
这似乎源于向量。
如何阻止我的 ram 使用量增加?
谢谢。
更新:
当我注释掉 while 循环中赋值的代码行时,我的 ram 使用率仍然快速增加
while (fIn >> dName >> dUssage) {
//primDataBank[counter].name = dName;
//primDataBank[counter].ussage = dUssage;
counter++;
}
然而,当我也注释掉矢量代码时,ram 使用率并没有增加:
//std::vector<worddata> primDataBank;
//primDataBank.resize(RAMALLOC);
您的内存使用量增加,因为您正在创建和存储从文件中读取的所有字符串。
字符串不是固定大小的对象,因此您可以为字符串预分配 space 的唯一方法是使用自定义分配器。
您应该更喜欢使用 reserve 和 emplace_back 而不是 resize 和设置字段,因为这将避免分配您不需要的 0 长度字符串。
我觉得你的更新令人难以置信。
您创建的向量大约使用
20000000 * 32 字节 = 640 000 000 即 640 MB // 谁说 640K 就足够了?
worddata 的大小来自 std::string 大约是 24 字节 + 8 字节。
然后你开始读取字符串,如果它们足够小,字符串可能会使用小字符串优化,即使用内部数据和容量来存储字符。
但如果它们大于 ~12(???) 个字符,则字符串会分配一个额外的数组来保留字符。
更新需要更多调查。
我正在使用以下代码将 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
占用。 "allocation call stack" 看起来像这样:
这似乎源于向量。
如何阻止我的 ram 使用量增加?
谢谢。
更新:
当我注释掉 while 循环中赋值的代码行时,我的 ram 使用率仍然快速增加
while (fIn >> dName >> dUssage) {
//primDataBank[counter].name = dName;
//primDataBank[counter].ussage = dUssage;
counter++;
}
然而,当我也注释掉矢量代码时,ram 使用率并没有增加:
//std::vector<worddata> primDataBank;
//primDataBank.resize(RAMALLOC);
您的内存使用量增加,因为您正在创建和存储从文件中读取的所有字符串。
字符串不是固定大小的对象,因此您可以为字符串预分配 space 的唯一方法是使用自定义分配器。
您应该更喜欢使用 reserve 和 emplace_back 而不是 resize 和设置字段,因为这将避免分配您不需要的 0 长度字符串。
我觉得你的更新令人难以置信。
您创建的向量大约使用
20000000 * 32 字节 = 640 000 000 即 640 MB // 谁说 640K 就足够了?
worddata 的大小来自 std::string 大约是 24 字节 + 8 字节。
然后你开始读取字符串,如果它们足够小,字符串可能会使用小字符串优化,即使用内部数据和容量来存储字符。 但如果它们大于 ~12(???) 个字符,则字符串会分配一个额外的数组来保留字符。
更新需要更多调查。