2016-06-19 4 views
4

Предположим, у меня есть следующий класс:Элементы, помещенные в unordered_map, хранящиеся в стеке или куче?

class MyOtherClass{ 
    std::unordered_map<int, std::multimap<int, MyClass*>> _xy; 

    void putObject(int x,int y,MyClass* obj); 
    void containsXkey(int x){ 
     bool found = false; 
     std::unordered_map<int,std::multi map<int,MyClass*>>::const_iterator index = _xy.find(x); 

     if(index = _xy.end(){ 
       found = false; 
     }else{ 
       found = true; 
     } 

      return found; 
    } 
} 

сказать, что я хочу, чтобы написать функцию, чтобы разместить MyClass в точке с координатами (2,3), то я бы сделать что-то вроде этого:

void putObject(int x, int y, MyClass* obj){ 
    if(!containsXKey(x){ 
      //Since it doesn't contain an empty multimap, I'm creating one. 
      std::multimap<int, MyClass*> foo; //This is created on the stack 
      _xy[x] = foo; //What happens here ? 
    } 

    std::multimap<int,MyClass*>& foo = _xy[x]; 
    foo.insert(y,obj); 
} 

Поэтому мой вопрос: сначала нет записей в unordered_map, поэтому в первый раз, когда я хочу добавить элемент в определенный ключ, мне нужно создать multimap. В стеке создается multimap. Итак, что происходит, когда я назначаю его ключу? Это сделать копию? Где он хранится?

+0

Нет таких вещей, как _stack_ или _heap_. 'std :: unordered_map' использует динамическое распределение памяти для хранения элементов карты (как это делают большинство других стандартных контейнеров). –

+0

Так что же происходит с мультимапом, который я создал? –

+1

Похоже, что он скопирован на '_xy [x]'. –

ответ

8

Как и все контейнеры с динамическим размером, контейнеры карт хранят свои элементы в динамической памяти * («куча» **).
сам объект может сидеть в стеке, куча или около того, но внутри объекта могут быть под-объекты или указатели, указывающие на динамическую память.

Итак, что происходит, когда я назначаю его ключу?

карта будет следить за тем, чтобы внутренний буфер мог удерживать другую пару ключ-значение, если нет, он будет расширяться для поддержки хранения еще одного элемента.

Это копия?

Это зависит от того, как ключ/значение было передано на карту. если ключ/значение поддерживает перемещение семантики и ключ был передан как r-значение-ссылка, он не будет скопирован, но вместо этого переместил. но если класс не поддерживает семантику перемещения или ключ передан как ссылка на const, он будет скопирован.

Где хранятся?

В стандарте не указывается, как карта должна быть реализована внутри страны, поэтому каждая библиотека может ее реализовать как угодно. Microsoft std::unordered_map хранит пару ключевых значений в связанном списке, другие библиотеки могут сохранить элементы карты в векторе или около того.

 std::multimap<int, MyClass*> foo; //This is created on the stack 
     _xy[x] = foo; //What happens here ? 

в этом случае foo создается на стеке. оператор [] сам создает созданный по умолчанию std::multimap в куче, тогда оператор = копирует содержимое foo (которые не являются) в _xy[y].

* Предполагая, что на карте используется стандартный распределитель, можно установить специальный распределитель, который выделяет память из другого хранилища.

** В стандарте не указаны слова типа «стек» и «куча» напрямую, но указаны следующие термины: автоматическое хранилище («стек»), динамическое хранилище («куча»), статическое хранилище (" сегмент данных ») и хранилище потоков (« TLS »).

+0

Со ссылкой на мой пример кода, было бы правильно сказать, что многократная карта, созданная в блоке if, находится в стеке, а то, что на самом деле хранится в unordered_map, является копией, находящейся в куче? –

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