2017-02-18 16 views
1

如果我有std::vector<std::set<int>>。如果插入过去的容量,矢量将重新分配。在矢量内有另一个可调整大小的类型的情况下,矢量是否只包含指向该类型的指针?C++包含容器的容器的增长?

特别是我想知道如何分配内存如果一个向量是任意类型。

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

'std :: set'是可移动的,或者你在问什么? –

+1

你在混合这些条款。矢量的大小是它所保存的元素的数量。在你的例子中,'b'的大小是10,它不会改变 – user463035818

+0

不一定是std :: set。如果我有一个向量,向量,并且被包含的类型在大小上发生变化,主向量是否会增长?我怎么知道它不会。编译器如何决定? –

回答

2

任何向量将自行分配的内存将始终为sizeof(element_type)* vector.size()。

该向量只能分配内存元素数据,在编译时可见。它不关心元素类所做的任何分配。

将矢量想象成类固醇上的数组。就像一个数组,一个向量由一个连续的内存块组成,其中所有元素都具有相同的大小。为了满足这个要求,它必须在编译时知道每个元素的大小。

试想一个std ::设置有这些成员变量:

struct SomeSet 
{ 
    size_t size; 
    SomeMagicInternalType* data; 
}; 

所以不管如何data在运行时分配,矢量只分配每个元素存储它所知道的编译时间

的sizeof(SomeSet ::大小)+的sizeof(SomeSet ::数据)

这将是4 + 4 32位机器上。

+0

我明白了,我担心变大的部分就在堆上。 –

0

A std::vector<T>保存T类型的对象。当它被调整大小时,它会根据需要复制或移动这些对象。 A std::vector<std::set<int>>也不例外;它拥有std::set<int>类型的对象。

3

C++对象只能有一个大小,但可能包含指向任意大小的堆内存的指针。所以,是的,容器对象本身通常包含一个指向堆内存的指针,可能不包含任何实际的项目。 (唯一的典型的例外是字符串类型,其有时具有“小串优化”,允许字符串对象到直接包含在对象小弦不分配堆内存。)

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的大小。