C++ 的向量如何分配内存
Posted
技术标签:
【中文标题】C++ 的向量如何分配内存【英文标题】:How C++'s Vector Allocate Memory 【发布时间】:2019-02-24 15:15:14 【问题描述】:考虑我的代码,我有向量 P,它的类型是粒子。那么Particle里面也有向量x、v和xBest。
所以,它是向量中的向量。
struct Particle
vector<double> x;
vector<double> v;
vector<double> xBest;
double fitness;
double pBest;
;
class Swarm
public:
vector<Particle> P;
Swarm();
;
因为在声明类或结构时编译器不允许我为向量保留内存。像这样:
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 中向量的大小尚未初始化,因此 Particle 的大小是未知的。但是我可以在 struct Particle 中为 3 个向量保留内存之前为 30 个粒子保留内存!!
这怎么可能?
【问题讨论】:
小心,reserve
只是分配存储空间,它实际上并不创建对象;因此,每个i
的P[I]
都是UB。请改用resize
。
vector<Particle> P(30);
在类声明中无效,但在 C++11 及更高版本中,您可以使用 vector<Particle> P30;
和 vector<Particle> P = vector<Particle>(30);
代替。 Proof
【参考方案1】:
这是未定义的行为。当你 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
s。
【讨论】:
【参考方案2】:在 C++ 中,每个对象所需的存储都是静态已知的,即在编译时。 C++ 中没有 VLA 之类的东西。 std::vector
不直接存储对象,它存储一个指向堆上数组的指针:
template <typename T>
class vector
// For illustration purposes only
T *array;
std::size_t size;
;
如您所见,向量的大小始终保持不变,无论它指向多少个元素,这就是您的示例(减去 cmets 中提到的 UB)有效的原因。
【讨论】:
以上是关于C++ 的向量如何分配内存的主要内容,如果未能解决你的问题,请参考以下文章