2017-02-18 4 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().

Вектор может выделять память для данных элемента, которая видна на время компиляции. Он не заботится о каких-либо выделениях класса элемента.

Подумайте о пакете как массив на стероидах. Подобно массиву, вектор состоит из непрерывного блока памяти, где все элементы имеют одинаковый размер. Чтобы заполнить это требование, во время компиляции он должен знать, насколько велика будет каждый элемент.

Представьте зЬй :: установить, чтобы эти переменные-члены:

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

Поэтому независимо от того, как data будет выделено во время выполнения, вектор только выделяет память для каждого элемента за то, что он знает, что в компиляции время:

SizeOf (SomeSet :: размер) + SizeOf (SomeSet :: данные)

Какой будет 4 + 4 на 32-битной машине.

+0

Я так вижу, что часть, которую я беспокоюсь о том, чтобы стать больше, находится в куче. –

0

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.

Смежные вопросы