我可以在C++中从const char*数组中进行std::字符串的零拷贝分配吗
Can I do a zero-copy std::string allocation in C++ from a const char * array?
对我的应用程序的分析显示,它在字符串分配上花费了近5%的CPU时间。在很多地方,我都在用64MB的字符缓冲区制作C++std::string对象。问题是,在程序运行过程中,缓冲区永远不会改变。我对std::string(const char *buf,size_t buflen)
调用的分析是,字符串正在被复制,因为在生成字符串后缓冲区可能会发生变化。这不是问题所在。有办法解决这个问题吗?
编辑:我正在处理二进制数据,所以我不能只传递char *s
。此外,由于std::string
避免了总是扫描NULL,我会有很大的开销。
如果字符串不会更改,并且它的寿命保证比您将要使用的字符串长,那么不要使用std::string
。
相反,考虑一个简单的C字符串包装器,如所提出的string_ref<T>
。
二进制数据?停止使用std::string并使用std::vector<char>
。但这并不能解决你被复制的问题。根据您的描述,如果这个巨大的64MB缓冲区永远不会改变,那么您真的不应该使用std::string或std::vector<char>
,无论哪种都不是好主意。你真的应该传递一个const char*指针(const uint8_t*更能描述二进制数据,但在掩盖之下,这是一样的,忽略了符号问题)。绕过指针和它的size_t长度,或者用另一个"end"指针传递指针。如果你不喜欢传递单独的离散变量(指针和缓冲区的长度),那么制作一个结构来描述缓冲区&让每个人都使用这些:
struct binbuf_desc {
uint8_t* addr;
size_t len;
binbuf_desc(addr,len) : addr(addr), len(len) {}
}
通过使用binbuf_desc
对象,您可以始终引用64MB缓冲区(或任何大小的任何其他缓冲区)。请注意,binbuf_desc对象并不拥有缓冲区(或其副本),它们只是缓冲区的描述符,因此您可以到处传递这些对象,而不必担心binbuf_desc会对缓冲区进行不必要的复制。
没有可移植的解决方案。如果你告诉我们你在使用什么工具链,有人可能知道你的库实现特有的技巧。但在大多数情况下,std::string
析构函数(和赋值运算符)将释放字符串内容,而不能释放字符串文字。(这并非不可能有例外,事实上,小字符串优化是跳过释放的常见情况,但这些都是实现细节。)
当您不需要/不想要动态分配时,最好不要使用std::string
。const char*
在现代C++中仍然运行良好。
由于C++17,std::string_view
可能是您的选择。它既可以从裸C字符串(有或没有长度)初始化,也可以从std::string
初始化
但是,data()方法返回一个以零结尾的字符串并没有任何约束。
如果你需要这种"请求时零终止"的行为,有其他选择,比如Adam Sawicki的str_view
,看起来很令人满意(https://github.com/sawickiap/str_view)
似乎使用const char *
而不是std::string
是最好的方法。但您也应该考虑如何使用字符串。可能存在从字符指针到std::string
对象的隐式转换。例如,这可能发生在函数调用期间。
- 在while循环中输入带有std::cin的字符串后,控制台会输出大量胡言乱语
- 如何在C++中用std::cout正确显示带十六进制的字符串文本
- 使用std::mt19937从字符串中返回一个随机单词
- 我可以重新分配/覆盖std::字符串吗
- 使用自定义比较函数使用std::sort()对矢量字符串进行排序时出现问题
- 如何将这个std::字符串转换为std::基本字符串
- 字符串化递归的"std::vector<std::vector<...>>"而不使用部分模板函数专用化
- std::字符串与 PCWSTR 的对话
- 确切地说,如何解释 std::getline(stream, string) 函数在C++中填充的字符串
- 将C++ std::string 转换为 UTF-16-LE 编码的字符串
- 使用 std::string_view 的子字符串控制台输出
- std::regex:匹配由数字和空格组成的字符串,并提取数字.如何?
- 重载 std::字符串运算符+ 用于打印枚举名称
- 从std::字符串创建OssBitString
- C++ TCP 套接字 | 无法将"std::__cxx11::字符串"转换为"const
- C 中的特殊字符的子字符串(STD :: substr)
- 是否建议将字符串std::移动到将被覆盖的容器中
- 显式指定要写入的字符串 std::ostringstream
- 如何将uint16_t转换为宽字符串(std::wstring)
- 读取和Huffman压缩4字节二进制字符串STD C++Linux环境