【发布时间】:2013-06-22 09:42:38
【问题描述】:
我是 C++ 新手,我在我的项目中使用矢量类。我发现它非常有用,因为我可以拥有一个在必要时自动重新分配的数组(即,如果我想 push_back 一个项目并且向量已经达到它的最大容量,它会重新分配自己,向操作系统请求更多内存空间),所以访问向量的元素非常快(它不像列表,要到达“n-th”元素,我必须经过“n”个第一个元素)。
我发现this question 非常有用,因为他们的回答完美地解释了当我想将向量存储在堆/堆栈上时 “内存分配器” 的工作原理:
[1] vector<Type> vect;
[2] vector<Type> *vect = new vector<Type>;
[3] vector<Type*> vect;
但是,一个疑问困扰了我一段时间,我找不到答案: 每当我构建一个向量并开始将 很多 项目推入时,它会达到向量已满的时刻,因此要继续增长,它需要重新分配,将自身复制到一个新位置并然后继续 push_back 项目(显然,这种重新分配隐藏在类的实现中,所以它对我来说是完全透明的)
好吧,如果我在堆上创建了向量 [2],我可以想象会发生什么:类向量调用 malloc,获取新空间,然后将自身复制到新内存中,最后删除旧内存免费通话。
但是,当我在堆栈上构造一个向量时,面纱隐藏了正在发生的事情 [1]:当向量必须重新分配时会发生什么? AFAIK,每当您在 C/C++ 上输入一个新函数时,计算机都会查看变量的声明,然后 展开 堆栈以获得放置这些变量所需的空间,但您无法分配当函数已经运行时,堆栈上有更多空间。类向量是如何解决这个问题的?
【问题讨论】:
-
显然,那个问题的答案根本没有完美地解释它,因为你的想法完全错误。
-
向量将其数据分配到可以在运行时增长的地方。矢量对象本身的大小保持固定,因为它为动态分配的数据保留了一个固定大小的句柄。
-
好的,有了下面的答案,我了解了向量对象的数据结构:就像下面的@juanchopanza 所说,它是一组指针,定义了位于堆上的数组的大小,其中存储了对象在上面。由于这个数组在堆上,如果需要更多空间,它可能会被重新分配。顺便说一句,对不起英语语法!我希望通过实践来改进它!
-
这是一个常见的误解,认为仅仅因为你说
std::vector<...> myvect;与std::vector<...> *myvect = new std::vector<...>;你最终会 - 对于内容 (!) - 使用 堆栈分配前者但 堆分配 后者。不是这样;而对于new ...的情况,堆几乎是有保证的,容器类型的内部实现决定了当你在本地实例化它时会发生什么。只有某些容器(即std::array)会嵌入它们的内容。std::vector没有。
标签: c++ vector stack allocator