我有一种情况,我需要处理大量(许多GB)的数据量:
每次迭代中的数据都是独立的.
我的问题是,我想最小化(如果可能消除)堆分配的内存使用量,因为它目前是我最大的性能问题.
有没有办法将C字符串(char*)转换为stl C++字符串(std :: string),而不需要std :: string来内部分配/复制数据?
或者,我可以使用stringstreams或类似的东西来重用大缓冲区吗?
编辑:感谢您的回答,为清楚起见,我认为修改后的问题将是:
如何有效地构建(通过多个附加)一个stl C++字符串.如果在循环中执行此操作,其中每个循环完全独立,我如何重新使用此分配的空间.
在C++ 11中,a的字符std::string必须连续存储,如第21.4.1/5节所述:
basic_string对象中的char类对象应连续存储.也就是说,对于任何basic_string对象,标识&*(s.begin()+ n)==&*s.begin()+ n应该适用于n的所有值,使得0 <= n <s.size ().
但是,这里是§21.4.7.1如何列出两个函数来检索指向底层存储的指针(强调我的):
const charT*c_str()const noexcept;
const charT*data()const noexcept;
1返回:指针p,使得p + i ==&operator [](i)为[0,size()]中的每个i.
2复杂性:恒定时间.
3要求:程序不得更改存储在字符数组中的任何值.
我可以想到的第3点的一种可能性是指针可以通过对象的以下用途而变得无效(第21.4.1/6节):
即便如此,迭代器也会失效,但我们仍然可以修改它们,无论它们是什么.我们仍然可以使用指针,直到它变为无效以便从缓冲区读取.
为什么我们不能直接写入这个缓冲区?是因为它会使类处于不一致状态,例如,end()不会使用新结束更新?如果是这样,为什么允许直接写入类似的缓冲区std::vector?
用例包括能够将a的缓冲区传递std::string给C接口以检索字符串而不是传入一个字符串,vector<char>并使用迭代器初始化字符串:
std::string text;
text.resize(GetTextLength());
GetText(text.data());
Run Code Online (Sandbox Code Playgroud) 在不使用boost的情况下,从字符串流中提取一组字符的正确c ++ 11方法是什么?
如果可能的话,我想在没有复制的情况下这样做,因为使用它的地方是关键数据循环.但是,似乎std :: string不允许直接访问数据.
例如,下面的代码执行字符串流中的子字符串副本:
inline std::string left(std::stringstream ss, uint32_t count) {
char* buffer = new char[count];
ss.get(buffer, count);
std::string str(buffer); // Second copy performed here
delete buffer;
return str;
}
Run Code Online (Sandbox Code Playgroud)
我的理解是矢量初始化每个角色,所以我想避免这种情况.
此外,这需要传递给一个接受const char*的函数,所以现在运行后我被迫做一个.c_str().这也是副本吗?
能够传回一个const char*会很好,但这似乎违背了"适当的"c ++ 11风格.
要了解我想要做什么,这里"有效"我想用它:
fprintf( stderr, "Data: [%s]...", left(ststream, 255) );
Run Code Online (Sandbox Code Playgroud)
但是c ++ 11强制:
fprintf( stderr, "Data: [%s]...", left(str_data, 255).c_str() );
Run Code Online (Sandbox Code Playgroud)
我在这里制作了多少份该字符串?
如何将它减少到只有一个副本的字符串流?