You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何将std::vector resize至小于reserve容量会擦除数据?如何保留数据?

关于std::vector resize擦除数据的问题解答

嘿,这个问题的核心是你混淆了reserve()和resize()的作用,而且直接操作reserve()后未被vector管理的内存属于未定义行为(UB),这才导致了看似奇怪的结果!

为什么你的代码里resize后数据没了?

先拆解下你的操作流程:

  1. 你调用vec_buff.reserve(32):这只是让vector提前分配了能装32个char的内存空间(容量capacity变成32),但vector的逻辑大小size还是0——也就是说,此时vector认为自己没有任何有效元素。
  2. 你直接通过vec_buff.data()[0]和[1]给内存赋值:这两个位置的内存虽然物理存在,但不属于vector管理的“有效元素”范围,vector完全不知道你在这里写了数据。
  3. 你调用vec_buff.resize(2):resize的作用是调整vector的逻辑size到指定值。因为原来的size是0,现在要变成2,vector会构造两个新的默认初始化的char元素(char的默认值是'\0'),这会覆盖你之前手动写入的那两个位置的内存,所以你之前写的0xA5和0xA6就被冲掉了。

简单说:你手动写的内存不在vector的“管辖范围”内,resize的时候vector会按自己的规则初始化新元素,自然就把你的数据覆盖了。

怎么在resize后保留数据?

要让vector承认你写入的数据是它的有效元素,你得先让这些元素被vector管理起来,有几种正确的做法:

方法1:先resize设置size,再操作元素

先通过resize把size调整到你需要的大小,此时vector会初始化对应数量的元素,之后你再修改这些元素就安全了:

#include <iostream>
#include <vector>
int main() {
    std::vector<char> vec_buff;
    vec_buff.reserve(32); // 可选,提前预留容量避免后续扩容
    vec_buff.resize(2);   // 先把size设为2,vector管理这两个元素
    vec_buff[0] = static_cast<char>(0xA5);
    vec_buff[1] = static_cast<char>(0xA6);
    
    std::cout << std::hex << static_cast<uint16_t>(vec_buff[0]) << std::endl;
    std::cout << std::hex << static_cast<uint16_t>(vec_buff[1]) << std::endl;
    
    vec_buff.resize(2); // 此时size已经是2,resize不会做任何修改,数据保留
    std::cout << std::hex << static_cast<uint16_t>(vec_buff[0]) << std::endl;
    std::cout << std::hex << static_cast<uint16_t>(vec_buff[1]) << std::endl;
    return 0;
}

方法2:用push_back/emplace_back添加元素

如果你不想提前设置size,可以用push_back逐个添加元素,vector会自动管理size:

#include <iostream>
#include <vector>
int main() {
    std::vector<char> vec_buff;
    vec_buff.reserve(32); // 提前预留容量
    vec_buff.push_back(static_cast<char>(0xA5));
    vec_buff.push_back(static_cast<char>(0xA6));
    
    std::cout << std::hex << static_cast<uint16_t>(vec_buff[0]) << std::endl;
    std::cout << std::hex << static_cast<uint16_t>(vec_buff[1]) << std::endl;
    
    vec_buff.resize(2); // size不变,数据保留
    std::cout << std::hex << static_cast<uint16_t>(vec_buff[0]) << std::endl;
    std::cout << std::hex << static_cast<uint16_t>(vec_buff[1]) << std::endl;
    return 0;
}

关键知识点总结

  • reserve():只修改vector的容量(capacity),不改变大小(size),超出size的内存是未初始化且未被管理的,直接操作属于UB。
  • resize():修改vector的size,当新size > 旧size时,会构造新元素(默认初始化);当新size < 旧size时,会销毁多余的元素,但不会释放内存(除非手动调用shrink_to_fit())。
  • 永远不要直接操作data()指向的、超出当前size的内存——那部分内存不属于vector的有效元素,vector随时可能覆盖它。

内容的提问来源于stack exchange,提问作者Harry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:26:35