Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/url/2.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
C++ 关于填充向量的不同方法_C++_Stdvector - Fatal编程技术网

C++ 关于填充向量的不同方法

C++ 关于填充向量的不同方法,c++,stdvector,C++,Stdvector,我可以想出三种填充std::vector 假设我们有 vector<int> v(100, 0); 或 v=向量(3,1); 我学会了另一种方法: vector<int>(3, 1).swap(v); vector(3,1).swap(v); 第一个问题是:它们中有哪一个是最好的方法 第二个问题:假设v是在主函数之外声明的。据此,将在数据段中分配内存。如果使用第二种或第三种方法,会在堆栈上分配内存吗 首先回答第二个问题:vector将始终为其包含的对象动态分配内

我可以想出三种填充
std::vector

假设我们有

vector<int> v(100, 0);

v=向量(3,1);
我学会了另一种方法:

vector<int>(3, 1).swap(v); 
vector(3,1).swap(v);
第一个问题是:它们中有哪一个是最好的方法


第二个问题:假设
v
是在主函数之外声明的。据此,将在数据段中分配内存。如果使用第二种或第三种方法,会在堆栈上分配内存吗

首先回答第二个问题:
vector
将始终为其包含的对象动态分配内存,因此它将最终位于堆上


至于哪种重新分配方法更好,我想说你的第一种或第二种方法使你的意图最清楚,这是最重要的属性。

你如何使用向量中的成员来完成这项任务

std::vector<int> v(100);
v.assign(3, 1); // this is what you should do.
标准:向量v(100); v、 分配(3,1);//这是你应该做的。
交换将有效地将向量缩减为3个元素。其他人可能不会

vector<int> v(100);
v.assign(3, 1);
assert(v.size() == 3);
assert(v.capacity() != 3);

v = vector<int>(3, 1);
// Now, v.capacity() is likely not to be 3.

vector<int>(3, 1).swap(v);
assert(v.capacity() == 3);
向量v(100); v、 分配(3,1); 断言(v.size()==3); 断言(v.容量()!=3); v=向量(3,1); //现在,v.capacity()可能不是3。 向量(3,1)。交换(v); 断言(v.capacity()==3);
其他方法不会在内部调整向量大小。即使size()成员返回3,它仍将在内存中占用100*sizeof(int)字节。尝试显示
v.capacity()
来说服自己。

因此,这里是不同之处,我将让您决定什么最适合您的情况

v.clear();
v.resize(3, 1);
在本例中,我们已将向量标记为已清除。它仍然保存为保存100个元素而分配的任何内容(这可能超过100个元素所需的空间)。然后我们添加了3个值为1的项目。所有这些只是增加了大小计数器并重置了3个值,底层内存仍然是相同的大小

v = vector<int>(3, 1);
v=向量(3,1);
除了创建一个额外的临时向量之外,这几乎是一样的,它不存在计数器为0然后为3的间歇位置,而是简单地复制计数器大小,然后执行类似于memcpy的操作来复制3个元素。分配给v的底层内存大小仍然足以容纳100个整数

vector<int>(3, 1).swap(v); 
vector(3,1).swap(v);
这一个明显不同。在本例中,我们创建一个临时向量,其中包含3个元素,这些元素都初始化为1。从理论上讲,它仍然可以为100个元素保留足够的内存,但很可能它的内存要少得多。然后我们用我们自己的向量交换这个向量,让临时向量被破坏。这还有一个额外的好处,那就是清除旧向量分配的临时内存之外的任何额外内存。其工作方式是两个向量(我们的v和临时向量)交换的不仅仅是计数器和值,它们还交换缓冲区指针


这是缩小向量的唯一方法。

在之前的文章中没有提到的一个问题,在选择这些备选方案时很重要。即异常安全。
向量(3,1).swap(v)具有强大的异常安全保证。形式
v=向量(3,1)也可能提供此类担保。第一种选择是不安全的:
v.clear();v、 调整大小(3,1)

那根本不是真的。基元数组将内存分配到声明它们的任何位置<代码>向量
将始终堆分配。int[]!=向量。忽略显而易见的东西是多么容易。这是
v.clear()的一个较短版本;v、 调整大小(3,1)具有相同的异常安全问题。几乎。我们不知道这些案例的实际占用面积。许多向量实现都会保留额外的空间,以便频繁的插入不会单独导致重新分配和移动。赋值运算符也可能在内部使用交换习惯用法,从而导致相同的内存减少,尽管这并不能保证。事实上,我不认为你能对这三种情况中的任何一种做出任何保证,只说明最有可能发生的情况。
v = vector<int>(3, 1);
vector<int>(3, 1).swap(v);