std::copy复制数组到vector时必须预先分配目标空间,否则越界导致未定义行为;正确做法是先resize或构造时指定大小,再用vec.begin()和vec.end()。

std::copy 复制数组到 vector 时迭代器范围必须匹配
直接用 std::copy 把 C 风格数组复制进 std::vector,最常出错的是目标空间没预留——std::copy 不会自动扩容,它只按你给的迭代器位置逐个赋值,越界就 UB。
正确做法是先调 vec.resize() 或构造时指定大小,再传 vec.begin() 和 vec.end():
int arr[] = {1, 2, 3, 4, 5};
std::vector<int> vec(5); // 必须提前分配 5 个元素
std::copy(std::begin(arr), std::end(arr), vec.begin());- 别用
vec.begin()+vec.size()算尾迭代器——vec.end()才是标准写法 - 如果 vector 原来不为空,且你想追加,得用
std::back_inserter(vec),但性能略低(每次 insert 调构造) -
std::begin(arr)和std::end(arr)比arr和arr + N更安全,尤其在模板里
复制到 deque 或 list 优先用 back_inserter
std::deque 和 std::list 不支持随机访问迭代器赋值(it = x),所以不能直接传 container.begin()——除非你已知容器长度且已清空、预留好空间。
更自然的做法是用 std::back_inserter,它把赋值转成 push_back:
立即学习“C++免费学习笔记(深入)”;
int arr[] = {10, 20, 30};
std::deque<int> deq;
std::copy(std::begin(arr), std::end(arr), std::back_inserter(deq));-
std::back_inserter内部调push_back,适用于任何带该接口的容器 - 对
std::vector来说,用back_inserter会触发多次可能的 realloc,不如先reserve()再用普通迭代器 -
std::front_inserter同理,但复制结果是逆序的,慎用
memcpy 比 std::copy 快?仅限 trivially copyable 类型
如果数组元素是 int、float、struct(无虚函数、无非 trivial 构造/析构),且目标内存已分配好,memcpy 确实更快——它直接搬字节,绕过构造/赋值逻辑。
但必须确保类型可平凡复制,否则行为未定义:
static_assert(std::is_trivially_copyable_v<int>); // ✅ static_assert(std::is_trivially_copyable_v<std::string>); // ❌
- 检查用
std::is_trivially_copyable_v<t></t>,别凭感觉 - 用
memcpy时,源/目标指针必须reinterpret_cast<uint8_t></uint8_t>,长度单位是字节:sizeof(int) * N -
std::copy是泛型安全的,memcpy是手动优化,别过早替换
std::copy 本身不保证“快速”,关键在内存布局和编译器优化
std::copy 是一个算法包装,底层是否展开成 memmove 或向量化指令(如 SSE/AVX),取决于编译器、STL 实现、O2/O3 优化等级,以及是否满足 trivially copyable + 连续内存 + 对齐等条件。
- Clang/GCC 在 -O2 下对
int数组常内联为rep movsd或向量化循环 - MSVC 的
std::copy在 /O2 下也会做类似优化,但对自定义类型不会退化成memcpy - 真正影响速度的往往是 cache 局部性:连续数组复制快,
std::list复制慢不是因为std::copy,而是节点分散
别迷信某个函数名自带“快速”属性,先看数据布局,再看类型特征,最后才决定要不要手动 memcpy —— 大多数场景下,std::copy 已经足够好,且更安全。


















