如何避免std::string resize时初始化内存?C函数写入场景优化
避免std::string resize初始化开销的方法
你当前的场景是通过网络获取非空终止的字符串及其长度,需要用C例程写入std::string的数据域,但std::string::resize()会初始化新分配的内存(如用'\0'填充),而你之后会完全覆盖这些内存,希望规避这部分额外的初始化成本。以下是几种可行方案:
通用最优方案(全C++版本适用):使用std::string::assign
如果你已经持有数据指针和明确的长度,无需先调用resize再手动拷贝,直接使用assign成员函数即可。它会自动分配足够的内存,直接将数据拷贝到std::string的缓冲区,全程不会执行多余的初始化操作——因为它明确知道你会用传入的数据填充整个缓冲区。
示例代码:
#include <string> #include <cstdio> #include <cstring> const char* str = "Some examplory string.."; int main() { const size_t len = strlen(str); std::string some_str; // 直接将len个字符从str拷贝到some_str,无额外初始化 some_str.assign(str, len); printf(some_str.c_str()); }
C++17及以上专属方案:使用std::string::resize_and_overwrite
如果你的场景是需要直接向std::string的内部缓冲区写入数据(比如从网络直接读取、调用C例程直接写入),resize_and_overwrite是专门为这类场景设计的成员函数。它会将std::string的大小调整为指定值,然后提供可写指针给回调函数,允许你直接写入数据,完全跳过初始化步骤。
示例代码:
#include <string> #include <cstdio> #include <cstring> const char* str = "Some examplory string.."; int main() { std::string some_str; const size_t len = strlen(str); // 调整大小到len,通过回调直接写入数据 some_str.resize_and_overwrite(len, [&](char* buf, size_t n) { std::memcpy(buf, str, n); return n; // 返回实际写入的长度 }); printf(some_str.c_str()); }
这种方法适合无需临时缓冲区的场景,能进一步减少内存拷贝开销。
C++17之前的折中方案(直接写入缓冲区场景)
如果你的编译器不支持C++17,又需要直接写入std::string的缓冲区,可借助std::vector<char>中转(注意:std::vector的默认构造/resize仍会初始化内存,仅适合对初始化开销不敏感的场景):
#include <string> #include <cstdio> #include <cstring> #include <vector> const char* str = "Some examplory string.."; int main() { const size_t len = strlen(str); std::vector<char> temp_buf(len); std::memcpy(temp_buf.data(), str, len); // 移动构造std::string,避免内存拷贝 std::string some_str(std::make_move_iterator(temp_buf.begin()), std::make_move_iterator(temp_buf.end())); printf(some_str.c_str()); }
内容的提问来源于stack exchange,提问作者glades
相关产品推荐
相关产品推荐

