我是C++的新手,正在我的项目中使用vector类。我发现这很有用,因为我可以拥有一个数组,每当需要时它会自动重新分配内存空间(例如,如果我想要添加一个元素到vector中,而且vector已经达到了它的最大容量,它就会向操作系统请求更多的内存空间),所以访问vector的元素非常快速(不像列表,我必须遍历前n个元素才能访问第n个元素)。
我发现这个问题非常有用,因为他们的答案完美地解释了当我想要将我的vector存储在堆栈上时,"内存分配器"如何工作:
[1] vector<Type> vect;
[2] vector<Type> *vect = new vector<Type>;
[3] vector<Type*> vect;
然而,有一个问题一直困扰着我,我找不到答案:每当我构造一个向量并开始推入大量的元素时,它会达到一个向量已满的时刻,所以为了继续增长它需要重新分配内存,在新位置上复制自身,然后继续推入元素(显然,这种重新分配在类的实现中是隐藏的,因此对我来说是完全透明的)。
好吧,如果我在堆上创建了这个向量[2],我可以想象可能发生了什么:类vector调用malloc,获取新空间,然后将自身复制到新内存中,最后通过调用free删除旧内存。
然而,当我在栈上构造一个向量[1]时,有一个面纱隐藏了正在发生的事情:当向量必须重新分配时会发生什么?据我所知,每当在C/C++中进入一个新函数时,计算机都会查看变量的声明,然后扩展栈以获得放置这些变量所需的空间,但是当函数已经运行时,无法在栈上分配更多的空间。那么类vector如何解决这个问题呢?
注: [1] 在栈上构造一个向量,意味着简单地使用vector my_vector(n)(其中n是足够大的)。 [2] 在堆上构造向量,即使用vector* my_vector = new vector(n)。
std::vector<...> myvect;
和std::vector<...> *myvect = new std::vector<...>;
这两种不同的语句,你就会在前者中得到 栈分配 而在后者中得到 _堆分配_。事实并非如此;虽然对于new ...
的情况,堆内存几乎是必然的,但容器类型的 内部实现 决定了当你在本地实例化它时会发生什么。只有某些容器(例如std::array
)会 嵌入 它们的内容。而std::vector
则不会。 - FrankH.