如果我有std::vector<std::set<int>>
。如果插入超过其容量,矢量将重新分配。如果向量中有另一个可调整大小的类型,向量是否只保存指向所述类型的指针?
特别是我想知道如果向量持有任意类型,如何分配内存。
std::vector<int> a(10); //Size will be sizeof(int) * 10
std::vector<std::set<int>> b(10);
b[0] = {0, 0, 0, 0, 0, 0, 0, .... }; //Is b's size effected by the sets inside?
答案 0 :(得分:3)
C ++对象只能有一个大小,但可能包含指向任意大小的堆内存的指针。所以,是的,容器对象本身通常包含指向堆内存的指针,并且可能不包含任何实际项目。 (唯一的例外是字符串类型,它有时会进行&#34;小字符串优化&#34;它允许字符串对象直接在对象中包含小字符串而不分配堆内存。)
答案 1 :(得分:2)
任何向量将“自己”分配的内存将始终为sizeof(element_type)* vector.size()。
向量只能为编译时时可见的元素数据分配内存。它不关心元素类所做的任何分配。
将矢量视为类固醇上的数组。像数组一样,向量由一个连续的内存块组成,其中所有元素都具有相同的大小。为了满足这个要求,它必须在编译时知道每个元素的大小。
想象一下std :: set有这些成员变量:
struct SomeSet
{
size_t size;
SomeMagicInternalType* data;
};
因此,无论data
如何在运行时分配 ,向量只会为编译时所知道的每个元素分配内存:
sizeof(SomeSet :: size)+ sizeof(SomeSet :: data)
在32位计算机上,这将是4 + 4。
答案 2 :(得分:1)
考虑这个例子:
#include <iostream>
#include <vector>
int main() {
std::vector<int> v;
std::cout << sizeof(v) << "\n";
std::cout << v.size() << "\n";
v.push_back(3);
std::cout << sizeof(v) << "\n";
std::cout << v.size() << "\n";
}
确切的数字可能会有所不同,但我得到的是输出:
24
0
24
1
添加元素时,vector
的大小(大小=对象大小)不会更改。对于set
也是如此,因此如果其中一个元素添加或删除元素,则vector<set>
不需要重新分配。
集合不会将其元素存储为成员,否则具有不同数量的元素的集合将是不同的类型。它们存储在堆上,因此不会直接影响set
的大小。
答案 3 :(得分:0)
std::vector<T>
包含T
类型的对象。调整大小后,它会根据需要复制或移动这些对象。 std::vector<std::set<int>>
没有什么不同;它包含std::set<int>
类型的对象。