为何将std::vector resize至小于reserve容量会擦除数据?如何保留数据?
关于std::vector resize擦除数据的问题解答
嘿,这个问题的核心是你混淆了reserve()和resize()的作用,而且直接操作reserve()后未被vector管理的内存属于未定义行为(UB),这才导致了看似奇怪的结果!
为什么你的代码里resize后数据没了?
先拆解下你的操作流程:
- 你调用
vec_buff.reserve(32):这只是让vector提前分配了能装32个char的内存空间(容量capacity变成32),但vector的逻辑大小size还是0——也就是说,此时vector认为自己没有任何有效元素。 - 你直接通过
vec_buff.data()[0]和[1]给内存赋值:这两个位置的内存虽然物理存在,但不属于vector管理的“有效元素”范围,vector完全不知道你在这里写了数据。 - 你调用
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
相关产品推荐
相关产品推荐

