gpt4 book ai didi

VS2008 中的 C++ STL:std::ostringstream 在大量分配/清除使用后抛出 std::bad_alloc

转载 作者:行者123 更新时间:2023-11-28 03:56:45 25 4
gpt4 key购买 nike

我遇到过这样一种情况(在 Win32 上),std::ostringstream 对象继续消耗进程内存,即使它在一系列追加类型操作后表面上已被清除。请看一下这个 C++ 片段:

int main(void)
{
std::ostringstream cOutputLogStream;

// Random long string
std::string sTest = "jkspoiauyeraspfoiusdfsdfekgpweojkgpwoekpokgkpgeopoegwj";

std::string sEmpty = "";

int n = 0;
int looper = 0;

while (n++ < 100000)
{
while (looper++ < 45)
{
cOutputLogStream << s;
}

cOutputLogStream.str(sEmpty);
cOutputLogStream.clear();

// This should give the heap manager a chance to consolidate
// fragmented memory blocks
Sleep(1);
}
}

在执行内部 while() 循环期间,在任务管理器中观察进程的内存使用情况显示持续上升,最终趋于平稳。但是,这种趋于平稳的情况与重复抛出错误 std::bad_alloc 的时间同时发生。这表明堆内存已经耗尽,或者请求的 block 大小在连续空间中不可用。

有没有其他人遇到过 ostringstream 对象的这种泄漏现象,还有什么其他替代对象可以代替这个不稳定的对象?

非常感谢!

最佳答案

我看不出这段代码如何重现问题。在 looper 递增到 45 之后,它应该消耗完所有内存。

一般的诊断是一个程序很少设法消耗所有可能的可用虚拟内存。它会首先在堆中找到足够大的连续字节 block 来存储字符串流缓冲区时死掉。它被称为地址空间碎片,对此您无能为力。您的 Sleep() 调用肯定不会做任何有用的事情,合并分配的堆 block 需要垃圾收集器。

另一个非常标准的陷阱是使用 TaskMgr.exe 诊断内存使用情况。它通常显示工作集,即映射到 RAM 的虚拟内存量。这通常只是您的程序消耗的虚拟内存量的一小部分,并且不能真正衡量您的程序消耗了多少虚拟内存。或者告诉您有关地址空间碎片的任何信息。

SysInternals 的 VMMap 实用程序可以显示您的程序如何使用虚拟内存。

关于VS2008 中的 C++ STL:std::ostringstream 在大量分配/清除使用后抛出 std::bad_alloc,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3247805/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com