考虑我的代码,我有向量P,其类型为粒子。然后在粒子内部还有向量x,v和xBest。
因此,它是vector内部的vectors。
struct Particle
{
vector<double> x;
vector<double> v;
vector<double> xBest;
double fitness;
double pBest;
};
class Swarm
{
public:
vector<Particle> P;
Swarm();
};
由于在声明类或结构时,编译器不会让我为vector保留内存。像这样:
class Swarm
{
public:
vector<Particle> P(30);
Swarm();
};
所以,我是在构造函数中这样做的:
Swarm::Swarm()
{
P.reserve(30);
for(size_t i = 0; i < 30; i++)
{
P[i].x.reserve(10);
P[i].v.reserve(10);
P[i].xBest.reserve(10);
}
}
而且有效。
我对此很好奇。由于结构粒子中向量的大小尚未初始化,因此粒子的大小未知。但是即使在 struct Particle 中为3个矢量保留内存之前,我也可以为30个粒子保留内存!
那怎么可能?
答案 0 :(得分:4)
这是未定义的行为。 reserve
向量时,您不会创建对象,因此循环如下:
for(size_t i = 0; i < 30; i++)
{
P[i].x.reserve(10);
P[i].v.reserve(10);
P[i].xBest.reserve(10);
}
正在对不存在的向量调用reserve
。
您不能在不存在的向量上保留容量。您需要先创建Particle
。
答案 1 :(得分:3)
在C ++中,每个对象所需的存储都是静态已知的,即在编译时。 C ++中没有VLA这样的东西。 std::vector
不直接存储对象,它存储指向堆上数组的指针:
template <typename T>
class vector {
// For illustration purposes only
T *array;
std::size_t size;
};
如您所见,向量的大小始终是恒定的,无论它指向多少元素,这就是示例(减去注释中提到的UB)起作用的原因。