可怕的迭代器失效(vector重新申请内存)

最后更新于:2022-04-01 06:44:05

##实战c++中的vector系列--可怕的迭代器失效(vector重新申请内存) vector给我们提供了很多的方便,但是偶尔也会有陷阱。当不注意的时候,就掉入其中。说到底,还是对vector的机制不够彻底掌握。 很轻松的写下这段代码: ~~~ #include<iostream> #include<vector> using namespace std; int main() { vector<int> v; v.push_back(1); std::vector<int>::iterator iter1 = v.begin(); v.push_back(1); int n = *iter1;//shit cout << n << endl; return 0; } ~~~ 上面的代码运行时崩溃,就是因为迭代器iter1在vector push_back新值后失效了。切记!  但是为什么会失效?  如果我先预先resize足够大,那么会如何呢? ~~~ #include<iostream> #include<vector> using namespace std; int main() { vector<int> v; v.resize(4); v.push_back(1); std::vector<int>::iterator iter1 = v.begin(); v.push_back(1); int n = *iter1; cout << n << endl; return 0; } ~~~ 上面的代码正常运行,因为之前resize了足够的空间,即迭代器不会失效。  我们就已给vector push_back两个元素为例。resize(1), resize(2), resize(3)程序还是会崩溃。还是容量不足,导致vector重新分配内存,而导致迭代器失效。 之前讲过了resize与reserve的区别,那么上面的代码如果使用reserve呢? ~~~ #include<iostream> #include<vector> using namespace std; int main() { vector<int> v; v.reserve(2); v.push_back(0); std::vector<int>::iterator iter1 = v.begin(); v.push_back(1); int n = *iter1; cout << n << endl; return 0; } ~~~ 还是以push_back两个元素为例,reserve(1)还是会导致崩溃,还是造成迭代器的失效。 接下来的问题就是vector的内存机制,当容量不够时,会申请多少内存?  还是写个程序看看: ~~~ #include<iostream> #include<vector> using namespace std; int main() { vector<int> v; for (int i = 1; i < 100; i++) { cout << "capacity:" << v.capacity() << ", " << "size" << v.size() << endl; v.push_back(i); } return 0; } //输出: capacity:0, size0 capacity:1, size1 capacity:2, size2 capacity:3, size3 capacity:4, size4 capacity:6, size5 capacity:6, size6 capacity:9, size7 capacity:9, size8 capacity:9, size9 capacity:13, size10 capacity:13, size11 capacity:13, size12 capacity:13, size13 capacity:19, size14 capacity:19, size15 capacity:19, size16 capacity:19, size17 capacity:19, size18 capacity:19, size19 capacity:28, size20 capacity:28, size21 capacity:28, size22 capacity:28, size23 capacity:28, size24 capacity:28, size25 capacity:28, size26 capacity:28, size27 capacity:28, size28 capacity:42, size29 capacity:42, size30 capacity:42, size31 capacity:42, size32 capacity:42, size33 capacity:42, size34 capacity:42, size35 capacity:42, size36 capacity:42, size37 capacity:42, size38 capacity:42, size39 capacity:42, size40 capacity:42, size41 capacity:42, size42 capacity:63, size43 capacity:63, size44 capacity:63, size45 capacity:63, size46 capacity:63, size47 capacity:63, size48 capacity:63, size49 capacity:63, size50 capacity:63, size51 capacity:63, size52 capacity:63, size53 capacity:63, size54 capacity:63, size55 capacity:63, size56 capacity:63, size57 capacity:63, size58 capacity:63, size59 capacity:63, size60 capacity:63, size61 capacity:63, size62 capacity:63, size63 capacity:94, size64 capacity:94, size65 capacity:94, size66 capacity:94, size67 capacity:94, size68 capacity:94, size69 capacity:94, size70 capacity:94, size71 capacity:94, size72 capacity:94, size73 capacity:94, size74 capacity:94, size75 capacity:94, size76 capacity:94, size77 capacity:94, size78 capacity:94, size79 capacity:94, size80 capacity:94, size81 capacity:94, size82 capacity:94, size83 capacity:94, size84 capacity:94, size85 capacity:94, size86 capacity:94, size87 capacity:94, size88 capacity:94, size89 capacity:94, size90 capacity:94, size91 capacity:94, size92 capacity:94, size93 capacity:94, size94 capacity:141, size95 capacity:141, size96 capacity:141, size97 capacity:141, size98 ~~~ 选几个数据分析一下:  0-1-2-3-4-6-9-13-19-28-42-63-94-141 从第二项开始:  2/2+2=3  3/2+3=4  4/2+4=6  6/2+6=9  9/2+9=13  13/2+13=19  19/2+19=28  28/2+28=42  42/2+42=63  63/2+63=94  94/2+94=141 **每次扩容50%**  删除容器中数据的时候,缓冲区大小并不会改变,仅仅只是清楚了其中的数据,只有在析构函数调用的时候vector才会自动释放缓冲区。
';