最直接的方案是用 std::vector::insert(v.begin(), x),因其封装了动态管理与插入逻辑;但频繁头部插入应选 std::deque::push_front(),均摊 o(1) 且避免搬移。

std::vector 的 insert() 是最直接的方案
原生 C 风格数组(比如 int arr[10])不支持头部插入——它内存固定、没有元数据,强行“插”只能靠手动搬移元素,既易错又低效。真正可行的做法是换用 std::vector,它底层虽也是连续内存,但封装了动态管理和插入逻辑。
头部插入用 insert() 最稳妥:
std::vector<int> v = {2, 3, 4};
v.insert(v.begin(), 1); // 插入后变成 {1, 2, 3, 4}</int>
-
v.begin()指向首元素,是头部插入的迭代器位置 - 时间复杂度是
O(n):所有原有元素都要往后挪一位,别指望常数时间 - 如果频繁头部插入,
std::vector不是最佳选择——考虑std::deque
为什么不用 memmove 手动搬移原始数组
有人会想:我有个 int arr[10],长度当前是 3,能不能用 memmove() 把 arr[0..2] 搬到 arr[1..3],再填新值到 arr[0]?理论上可以,但实际极易出错:
- 必须严格保证目标区域不重叠且有足够空间,
memmove()虽能处理重叠,但偏移算错就直接越界 - 你需要额外维护“当前有效长度”,否则下次插入时不知道从哪搬、搬多少
- 没有容量检查:插满就崩溃,得自己写扩容逻辑(等价于重复造
std::vector) - 类型无关性差:对
std::string或自定义类,memmove()会跳过构造函数,导致对象状态损坏
std::deque 更适合高频头部插入
如果业务明确要求“大量、反复在开头增删”,std::vector 的每次 insert(v.begin(), x) 都要移动全部元素,性能会明显下滑。这时 std::deque 是更自然的选择:
std::deque<int> d = {2, 3, 4};
d.push_front(1); // O(1) 均摊,不搬移数据</int>
-
push_front()和push_back()都是均摊O(1),内部用分段连续内存实现 - 随机访问仍是
O(1),和vector一样可下标取值(d[0]合法) - 缺点:迭代器失效规则更复杂;内存占用略高;缓存局部性略差(不过对头部插入场景影响小)
别忽略 move 语义和类型约束
无论用 vector::insert() 还是 deque::push_front(),传入的新元素若为临时对象或右值,编译器会自动触发移动构造(前提是类型支持),避免深拷贝开销:
- 对
std::string、std::vector等类型,移动比拷贝快得多 - 如果你的自定义类没写移动构造函数,插入时仍会调用拷贝构造——记得加
T(T&&) = default; - 插入失败只可能发生在内存分配阶段(抛
std::bad_alloc),其他情况不会静默失败
头部插入本身很简单,难的是选对容器和理解背后的代价——vector 适合“偶尔插、主要查”,deque 适合“插得多、也查得勤”。硬啃原始数组搬移,只会把边界条件和生命周期问题留到运行时。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











