我编写了以下代码来测试向量的容量值,当它是从另一个构造时。这是受到here提问的启发。
#include <iostream>
#include<vector>
int main()
{
std::vector<int> a;
a.reserve(65536);
a[0]=10;
std::vector<int> b(a); //NOTE: b is constructed from a
std::cout<<a[0]<<" " <<b[0];
}
程序编译成功,但运行时它抛出以下错误
Error during execution:
Segmentation Fault(core dumped).
然后检查该值是否已初始化为 vector a ,我更改了代码,如下所示:
#include <iostream>
#include<vector>
int main()
{
std::vector<int> a(65536);
a[0]=10;
std::vector<int> b(a); //NOTE: b is constructed from a
std::cout<<a[0];
}
这次程序成功运行且没有错误,输出为:
Output:
10
然后我尝试将其更改为以下代码:
#include <iostream>
#include<vector>
int main()
{
std::vector<int> a(65536);
a[0]=10;
std::vector<int> b(a); //NOTE: b is constructed from a
std::cout<<a[0]<<" " <<b[0];
}
令我惊讶的是,以下输出符合预期:
Output:
10 10
我无法理解为什么程序在构造函数中使用它的大小初始化向量时成功运行,但是当使用 reserve()给出容量时却无法运行。
我也知道使用 reserve()的矢量保留容量不会初始化矢量的大小。以下代码也让我更加困惑。
#include <iostream>
#include<vector>
int main()
{
std::vector<int> a;
a.reserve(1);
for(int i=0;i<5;i++)
a[i]=i;
std::vector<int> b(a); //NOTE: b is constructed from a
for(int i=0;i<5;i++)
std::cout<<a[i]<<" ";
std::cout<<"\n"<<a.size()<<" "<<a.capacity();
}
执行时会显示以下奇怪的输出:
Output:
0 1 2 3 4
0 1
向量存储了5个值,但向量的大小保持为0。
我无法理解矢量的这种行为。如何才能接受大小不变的值。
答案 0 :(得分:2)
您正在混合容量和大小。容量只是一个实现功能。它允许您通过指定向量最终将包含多少元素来优化内存分配,因此每次向量增长时其实现都不必重新分配内存(实际增长策略也是实现细节) )。
尺寸是合乎逻辑的。它定义了实际存在的元素数量。它绝不能超过容量(事实上,如果向量调整大小,容量将根据需要增长。)
访问0 .. size - 1
范围之外的元素是非法的,根据您的运气可能会也可能不会中断,无论容量是多少。这称为未定义的行为。
因此,当您调用方法或使用构造函数时,您必须确定它是设置容量还是大小。
答案 1 :(得分:1)
这是不允许的,你只是在有效记忆之外写的。
std::vector<int> a;
a.reserve(65536);
a[0]=10;
您需要使用构造函数
std::vector<int> a(65536);
a[0]=10;
或resize
std::vector<int> a;
a.resize(65536);
a[0]=10;
或push_back
std::vector<int> a;
a.reserve(65536);
a.push_back(10);
reserve
更改了向量的可用capacity
,resize
更改了向量的实际size
。 You can read more about that here
答案 2 :(得分:0)
std::vector
的{{3}}将为元素预先分配,但这并不意味着元素已创建,并且在不创建元素的情况下访问a[0]
也是非法的。
您可以使用reserve()
创建元素。试试这个:
#include <iostream>
#include<vector>
int main()
{
std::vector<int> a;
a.resize(65536);
a[0]=10;
std::vector<int> b(a); //NOTE: b is constructed from a
std::cout<<a[0]<<" " <<b[0];
}