假设你很富有(也许你是,也许你不是……无所谓!)
由于你很富有,你在摩尔岛(风暴群岛,法属波利尼西亚)上购买了一块土地。你非常确定这是一块好地产,所以你在那个岛上建了一座别墅并住在那里。你的别墅有一个游泳池、一个网球场、一个大车库,甚至还有更多漂亮的东西。
过了一段时间,你觉得摩尔岛变得非常无聊,因此你卖掉了你的土地和别墅,并决定搬到其他地方去。
如果你过一段时间回来,你可能会遇到很多不同的事情,但你不能确定其中任何一件事。
- 你的别墅可能已经消失,被俱乐部酒店取代。
- 你的别墅可能仍然在那里。
- 该岛可能已经沉没。
- ......
谁知道呢?即使别墅不再属于你,你可能还能跳进游泳池或者再次打网球。甚至可能有另一个别墅在旁边,你可以在一个更大的游泳池里游泳,没有人会干扰你。
如果你再次回来,你无法保证你会发现什么,这与我查看的实现中包含三个指针的向量是一样的:
begin
指向分配的内存位置的开始(即 X)
end
指向分配的内存的末尾 +1(即 begin+4)
last
指向容器中的最后一个元素 +1(即 begin+4)
通过调用 clear 函数,容器可能会销毁所有元素并重置 last = begin;
。函数 size()
很可能会返回 last-begin;
,因此你将观察到一个大小为 0 的容器。尽管如此,begin
可能仍然有效,并且可能仍有内存分配(end
可能仍然是 begin+4
)。你甚至可以在 clear() 之前设置的值。
std::vector<int> a(4);
a[2] = 12;
cout << "a cap " << a.capacity() << ", ptr is " << a.data() << ", val 2 is " << a[2] << endl;
a.clear();
cout << "a cap " << a.capacity() << ", ptr is " << a.data() << ", val 2 is " << a[2] << endl;
打印:
一个 cap 4,ptr 是 00746570,val 2 是 12
a cap 4,ptr 是 00746570,val 2 是 12
为什么没有观察到任何错误呢?这是因为 std::vector<T>::operator[]
不执行任何越界检查(与 std::vector<T>::at()
相反)。
由于 C++ 中不存在 "segfaults",所以您的程序似乎运行正常。
注意:在 MSVC 2012 上,如果在调试模式下编译,则 operator[]
执行边界检查。
欢迎来到未定义行为的世界!事情可能发生或可能不会发生。您可能连一个单独的情况都不能确定。
您可以冒险并大胆地研究它,但这可能不是生成可靠代码的方法。
at
运算符,它会进行边界检查并引发异常。我建议使用at
而不是[]
。 - Bill