我正在开发一个相当大而复杂的系统,并试图确保它从一开始就尽可能地防水。在运行一些内存检查时,我注意到使用字符串流时有些奇怪:当它们被删除/超出范围时,它们似乎总是释放所有内存。
我已经尝试在互联网上搜索答案,但大多数都是旧的(可能已经过时)和/或更关心刷新内容而不是释放内存,所以我还没有真正去过能够判断它是否是一个已知问题或我正在制造的常见错误。
我写了一个简单的测试来展示正在发生的事情:
#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
using namespace std;
float getMemUsage(int& pid)
{
if (pid < 0)
pid = getpid();
char buf[30];
snprintf(buf, 30, "/proc/%u/statm", (unsigned)pid);
FILE* pf = fopen(buf, "r");
if (pf)
{
unsigned size; // total program size
//unsigned resident;// resident set size
//unsigned share;// shared pages
//unsigned text;// text (code)
//unsigned lib;// library
//unsigned data;// data/stack
//unsigned dt;// dirty pages (unused in Linux 2.6)
fscanf(pf, "%u" /* %u %u %u %u %u"*/, &size/*, &resident, &share, &text, &lib, &data*/);
fclose(pf);
return size/1024.0;
}
else
return -1.0;
}
int main(int argc, char* argv[])
{
if (argc < 2)
cerr << "no file specified\n";
ifstream file;
file.open(argv[1]);
int pid = -1;
const float memUseAtStart = getMemUsage(pid);
{
float memUseBefore = getMemUsage(pid);
stringstream sstream;
float memUseAfter = getMemUsage(pid);
cerr << "\tMemory use change after stringstream declaration: " << memUseAfter - memUseBefore << endl;
memUseBefore = getMemUsage(pid);
filebuf* pbuf = file.rdbuf();
memUseAfter = getMemUsage(pid);
cerr << "\tMemory use change after getting file buffer: " << memUseAfter - memUseBefore << endl;
memUseBefore = getMemUsage(pid);
sstream << pbuf;
memUseAfter = getMemUsage(pid);
cerr << "\tMemory use change after copying file contents: " << memUseAfter - memUseBefore << endl;
memUseBefore = getMemUsage(pid);
sstream.clear();
sstream.str( string() );
memUseAfter = getMemUsage(pid);
cerr << "\tMemory use change after 'clearing': " << memUseAfter - memUseBefore << endl;
}
cerr << "Overall memory use change: " << getMemUsage(pid) - memUseAtStart << endl;
file.close();
return 0;
}
当使用大于32K的文件调用时,它给出了以下输出:
Memory use change after stringstream declaration: 0
Memory use change after getting file buffer: 0
Memory use change after copying file contents: 0.0322266
Memory use change after 'clearing': 0
Overall memory use change: 0.00195312
我在Linux上运行(SL6.6)并使用gcc 4.1.2进行编译(虽然我也尝试过clang和ICC,结果相似)。
显然,这不是一个巨大的泄漏;它只是有点烦人,我不能让它完全整洁......我能做什么/应该做什么来手动释放内存?或者它只是一些奇怪的东西(我的设置和/或字符串流本身)我将不得不忍受?NB stringstream的用途是读入上面的一些文件内容,然后逐行解析它们;我会尝试使用istringstream,但我无法弄清楚如何从ifstream设置其值......
谢谢!