关于C++ vector容器size()与resize()函数的行为疑问
嘿,这个问题其实是C++新手用vector时很容易踩的坑,咱们把它掰碎了说清楚~
首先,你忽略了两个核心要点:vector的size和capacity的区别,以及operator[]的无边界检查特性。
1. resize()到底做了什么?
当你调用vector_a.resize(2)时,你是在告诉vector:把当前**实际存在的元素数量(size)**调整为2。因为原来的size是3,所以vector会销毁第3个元素(索引为2的那个),此时vector_a.size()返回2完全符合预期。
但这里要注意:resize()只会改变size,不会主动缩小vector的底层数组容量(capacity)。你之前push_back了3个元素,vector的capacity至少是3,resize(2)之后,capacity还是3——也就是说底层数组的那块内存还在,只是vector不再把索引2的位置视为有效元素了。
2. operator[]为什么能访问超出size的索引?
std::vector的operator[]是一个“不安全”的访问方式:它不会做边界检查。当你写vector_a[2]时,程序直接去访问底层数组中索引为2的内存位置,不管这个位置是不是vector的有效元素。
你现在能赋值、能访问,纯粹是因为那块内存还没被系统回收或者其他变量覆盖,但这属于未定义行为——换个编译器、换个运行环境,程序可能直接崩溃,或者输出奇怪的结果,绝对不能这么写!
如果想要安全的边界检查,应该用vector_a.at(2),这个方法会检查索引是否在0到size()-1之间,超出范围会直接抛出std::out_of_range异常,帮你及时发现问题。
3. 正确的做法是什么?
如果你想给vector添加第3个元素,应该用push_back()或者emplace_back(),而不是直接访问超出size的索引:
// Example program #include <iostream> #include <vector> int main() { struct struct_1 { int variable_1; int variable_2; }; std::vector<struct_1> vector_a; vector_a.push_back(struct_1()); vector_a.push_back(struct_1()); vector_a.push_back(struct_1()); vector_a.resize(2); vector_a[0].variable_1 = 21; vector_a[0].variable_2 = 34; vector_a[1].variable_1 = 111; vector_a[1].variable_2 = 764; // 正确添加第3个元素 vector_a.push_back(struct_1{5656, 5666764}); std::cout << "size " << vector_a.size() << std::endl; // 此时size会输出3 }
补充:size vs capacity的核心区别
- size:vector中当前有效元素的数量,也就是你能合法访问的元素范围是
0到size()-1; - capacity:vector底层数组已经分配的内存能容纳的元素数量,capacity >= size,当你添加元素导致size超过capacity时,vector会重新分配更大的内存块。
如果你想让capacity和size一致,可以在resize之后调用vector_a.shrink_to_fit(),不过这只是一个请求,编译器不一定会执行。
内容的提问来源于stack exchange,提问作者mjcmsp

