c++oding="utf-8" ?>
必须手动补'\0':std::copy(str.begin(), str.end(), dest)拷贝内容后,需dest[str.length()] = '\0';目标数组大小至少为str.length()+1,否则printf等函数行为未定义。

std::copy 拷贝 string 到 char 数组的基本写法
必须确保目标 char 数组足够大,且手动补 '\0' —— std::copy 不处理空终止符,也不会检查边界。
常见错误是数组长度刚好等于 str.length(),结果拷贝后没位置放 '\0',导致后续 printf 或 strlen 行为未定义。
正确做法:
- 目标数组大小至少为
str.length() + 1 - 用
std::copy(str.begin(), str.end(), dest)拷贝内容 - 显式写入
dest[str.length()] = '\0'
示例:
std::string str = "hello"; char buf[6]; std::copy(str.begin(), str.end(), buf); buf[str.length()] = '\0'; // 必须这一步
为什么不能直接用 std::copy_n 或 memcpy?
std::copy_n 看似更直观(指定拷贝长度),但它不接受 str.end() 这类半开区间,容易传错长度;而 memcpy 虽快,但要求源/目标非重叠且类型可平凡复制——对 char 没问题,但失去泛型适应性,且同样不加 '\0'。
关键区别:
-
std::copy基于迭代器,语义清晰,与容器解耦 -
std::copy_n需你手动传str.length(),多一次计算,还可能和str.size()混用(二者等价,但易读性差) -
memcpy是 C 风格,无类型安全,编译器无法做迭代器相关优化(如 SSO 字符串的短路径)
遇到 const char* 目标或只读内存怎么办?
如果目标是 const char*(比如指向文字常量区的指针),std::copy 编译直接失败 —— 迭代器解引用后是 const char&,不能赋给 char&。
此时必须换目标:要么用非常量数组,要么用 std::vector<char></char>,再取 .data()。
错误示范:
const char* dst = "xxxxx"; // 只读 std::copy(s.begin(), s.end(), dst); // ❌ 编译不过
正确做法:
- 用
std::vector<char> buf(s.length() + 1)</char>,再std::copy,最后buf.back() = '\0' - 或改用
str.copy(buf, s.length())(string::copy成员函数,会返回实际拷贝数,但也不加'\0')
性能和兼容性要注意什么?
std::copy 在优化开启时(-O2)通常被内联为 memmove 或 rep movsb,性能不输 memcpy;但在 debug 模式下有迭代器调试检查(如 libstdc++ 的 _GLIBCXX_DEBUG),可能变慢。
跨平台兼容性没问题,但注意:
- 某些嵌入式 STL 实现可能没完全实现
std::copy的 SFINAE 优化,对小字符串未必自动退化为memcpy - 若目标数组在栈上且很大(比如 >4KB),要考虑栈溢出风险,此时应优先用
std::vector<char></char> -
std::string含空字符'\0'时,std::copy照常拷贝全部字节 —— 这和c_str()不同,后者只保证前缀零终止
最易被忽略的一点:拷贝后忘记置 '\0',尤其当目标数组复用、或后续要传给 C 函数时,静默崩溃比报错更难排查。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











