C ++的向量如何分配内存

时间:2019-02-24 15:15:15

标签: c++ c++11 memory vector

考虑我的代码,我有向量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个粒子保留内存!

那怎么可能?

2 个答案:

答案 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)起作用的原因。