使用大长度缓冲区进行串流初始化是否会增加内存使用量

问题描述:

假设我有一个长度为100MB的缓冲区char[100*1024*1024]。我想在这个缓冲区上使用stringstream工具,就像读取格式一样,所以我使用这个数组定义了一个新的stringstream ss(arr)。所以我想知道我的程序在运行时是否总共使用200MB?我正在处理大数据,内存使用情况至关重要。实际上我定义了一个char缓冲区,并用这个缓冲区初始化我的自定义istream并解决了我的内存问题。但是我的第二种方式是否多余,我仍然困惑不解。使用大长度缓冲区进行串流初始化是否会增加内存使用量

+0

你为什么不简单*自己测量一下? –

+0

我尝试通过更改原始缓冲区,因为它预期它不会影响串流。使用其他工具,如valgrind,Xcode我无法得到它,他们没有显示关于stringstream内部机制的信息。由于这是一个关键问题,我只想确定stringstream何时被初始化,并且array有缓冲区大小的内存分配。 –

+2

很确定你会有重复。我没有从标准中读取任何确定的信息,但'stringstream'包含一个'stringbuf','stringbuf'通常需要一个可调整大小的字符序列。你的数组不可调整大小。可能发生的情况是,你的100 MB缓冲区将被转换为一个'std :: string','string'将构成'stringbuf'的基础。 – user4581301

所以我想了解一下,如果我的程序在运行时总共使用200MB或者不是在运行时 ?

如果你从一个字符数组它将至少双倍的内存使用量构造一个stringstream。从std::basic_stringstream constructor参考:

使用STR的副本作为基础字符串 装置的初始内容。

你可以编写自己的流缓冲区创建一个非所属的stringstream,但boost::iostreams库中已经提供了通过array devices

namespace io = boost::iostreams; 

char str[100*1024*1024]; 

// No copy of str is made here! The stream just stores pointer and size of array. 
io::stream<io::array_source> strm(str, sizeof(str)); 

// Do something with the stream as usual. It is fully compatible with standard streams. 
int x; 
strm >> x; 

有一个很好的在线编译显示峰值内存使用量。 在以下示例中,我将从10 MiB阵列创建一个流。

Live example using std::stringstream。 31(!)MiB的高峰。

Live example using boost::array_source。只有11 MiB的高峰。

为什么在使用std::stringstream时甚至有一个峰值内存使用率甚至是3x char数组大小?因为我们必须首先从char数组中创建一个临时的string,因为std::stringstream没有一个构造函数接受char指针。