jha*_*a-G 5 c++ python vector leaky-abstraction
以下代码片段提供了非常奇怪的输出.我期待溢出(Python给出一个MemoryError)
#include <iostream>
#include <vector>
int main()
{
std::vector<int> a{1,2,3};
for( auto const & item : a)
a.push_back(item);
for( auto const & item : a)
std::cout<<item<<',';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
产量:1,2,3,1,0,3,
我该如何解释这个结果?
如果你在Python中做类似的事情,它会给出内存错误.
>>> a = range(0,20)
>>> for i in a:
a.append(i)
Traceback (most recent call last):
File "<pyshell#3>", line 2, in <module>
a.append(i)
MemoryError
>>>
Run Code Online (Sandbox Code Playgroud)
我想到了这个问题,因为上面编写代码的方式被认为是绑定安全的.并且对于绑定的安全容器不应该在生长/收缩期间foreach type iteration.所以,这是一个漏洞的抽象.
有没有办法可以包装这个foreach循环,以便在循环体中不允许任何导致大小修改/重新分配的操作.
Som*_*ude 10
在C++中,向向量添加元素可能会导致重新分配包含的数据,这将使所有迭代器无效.这意味着您不能使用迭代器(这是基于范围的for循环)循环遍历向量,同时还插入新元素.
但是,您可以使用索引进行迭代并使用向量大小作为条件,因为索引将始终相同.
如果调整向量的大小,迭代器将变得无效。
如果你提前预约的话是可以的。
请记住,它将for range在进行任何更改之前定义的迭代器边界上进行操作。因此只会获得附加列表的副本。
#include <iostream>
#include <vector>
int main()
{
std::vector<int> a{1,2,3};
a.reserve(10); // 10 should be enough to get a copy without reallocating
for( auto const & item : a)
a.push_back(item);
for( auto const & item : a)
std::cout<<item<<',';
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
1,2,3,1,2,3,
Run Code Online (Sandbox Code Playgroud)
我不会推荐这样的方法,因为我认为它不干净或清晰。但是,如果您参考该标准,则预期会出现以下行为:
23.3.6.5向量修饰符
关于insert, emplace, emplace_back,的使用push_back。
备注:如果新大小大于旧容量,则导致重新分配。如果没有发生重新分配,则插入点之前的所有迭代器和引用仍然有效。
也就是说,如果没有发生重新分配,您可以信任插入点之前的迭代器。因此,只要向量的容量足够高,就可以毫无问题地进行追加。
| 归档时间: |
|
| 查看次数: |
1878 次 |
| 最近记录: |