Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/156.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python C++;:在迭代时将_推回std::vector_Python_C++_Vector_Leaky Abstraction - Fatal编程技术网

Python C++;:在迭代时将_推回std::vector

Python C++;:在迭代时将_推回std::vector,python,c++,vector,leaky-abstraction,Python,C++,Vector,Leaky Abstraction,下面的代码片段提供了一个非常奇怪的输出。我预计会出现溢出(Python给出了一个MemoryError) #包括 #包括 int main() { std::向量a{1,2,3}; 用于(自动常数和项目:a) a、 推回(项目); 用于(自动常数和项目:a) 标准::cout>>对于a中的i: a、 附加(i) 回溯(最近一次呼叫最后一次): 文件“”,第2行,在 a、 附加(i) 记忆者 >>> 我想到了这个问题,因为上面的代码编写方式被认为是绑定安全的。对于绑定安全性,容器不应该在每个类

下面的代码片段提供了一个非常奇怪的输出。我预计会出现溢出(Python给出了一个MemoryError)

#包括
#包括
int main()
{
std::向量a{1,2,3};
用于(自动常数和项目:a)
a、 推回(项目);
用于(自动常数和项目:a)
标准::cout>>对于a中的i:
a、 附加(i)
回溯(最近一次呼叫最后一次):
文件“”,第2行,在
a、 附加(i)
记忆者
>>> 

我想到了这个问题,因为上面的代码编写方式被认为是绑定安全的。对于绑定安全性,容器不应该在每个类型迭代的
foreach-type-iteration
期间增长/收缩。因此,这是一个泄漏的抽象


有一种方法可以包装这个<代码>前缀< /Cord>循环,因此在循环体中不允许任何大小修改/重新分配的操作。C++中的< /p> 在向量中添加元素可能导致包含数据的重新分配,这将使所有迭代器无效。这意味着不能使用迭代器循环向量。(这就是基于范围的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;
}
我不推荐这样的方法,因为我不认为它是干净的或清晰的。但是,如果你参考这个标准,这种行为是预期的:

23.3.6.5矢量修改器

关于
插入
安放
安放
推回

备注:如果新大小大于旧容量,则会导致重新分配。如果没有重新分配,则插入点之前的所有迭代器和引用仍然有效


也就是说,如果没有重新分配,您可以在插入点之前信任您的迭代器。因此,只要向量的容量足够大,您就可以毫无问题地进行追加。

我怀疑这样做是未定义的行为。@Gautam Jha我认为在回答问题后更改/扩展您的问题有点不公平……意识到了这一点我的意图不是很清楚,问一个新的问题,类似的数据是没有意义的。好吧,我认为你现在在最后两段中问了一个不同的问题。为什么C++没有STD::向量常量的大小,即没有重新分配。因为上面的代码没有任何意义。<代码>:STD::向量< /代码>能够G。行。如果您希望大小保持不变,您应该
使用std::array
我想到了这个问题,因为上面的代码编写方式被认为是绑定安全的。这不是一个漏洞吗abstraction@mtk99然而,
std::vector
std::array
之间还有另一个重要的区别,这可能使
std::arrayunisable:向量在堆上分配内存,而数组在堆栈上分配(如果定义为局部变量)在编译时,编译器编译了一些关于C++标准的信息,这个问题出现在我的脑海中,因为上面写代码的方式被认为是安全的。它不是一个漏洞百出的抽象,C++委员会的每个人都主张这些循环和凭证用于绑定安全。g常数我们无法实现绑定安全。这个答案是金色的。我的耳朵因为这个问题而流泪。
>>> 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

>>> 
#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;
}
1,2,3,1,2,3,