Когда векторы распределяются, они используют память в куче или стеке? - PullRequest
136 голосов
/ 07 ноября 2011

Верны ли все следующие утверждения?

vector<Type> vect; //allocates vect on stack and each of the Type (using std::allocator) also will be on the stack

vector<Type> *vect = new vector<Type>; //allocates vect on heap and each of the Type will be allocated on stack

vector<Type*> vect; //vect will be on stack and Type* will be on heap. 

Как выделяется внутренняя память для Type в vector или любом другом контейнере STL?

Ответы [ 4 ]

191 голосов
/ 07 ноября 2011
vector<Type> vect;

выделит vector, то есть информацию заголовка, в стеке, но элементы в свободном хранилище ("куча").

vector<Type> *vect = new vector<Type>;

выделяет все в свободном хранилище.

vector<Type*> vect;

выделит vector в стеке и кучу указателей в бесплатном хранилище, но где эти точки определяются тем, как вы их используете (вы можете указать элемент 0 на бесплатное хранилищеи элемент 1 в стек, скажем).

23 голосов
/ 07 ноября 2011

Предполагая реализацию, у которой на самом деле есть стек и куча (стандарт C ++ не требует таких вещей), единственное верное утверждение - последнее.

vector<Type> vect;
//allocates vect on stack and each of the Type (using std::allocator) also will be on the stack

Это верно, за исключением последней части (Type не будет в стеке).Представьте себе:

  void foo(vector<Type>& vec) {
     // Can't be on stack - how would the stack "expand"
     // to make the extra space required between main and foo?
     vec.push_back(Type());
  }

  int main() {
    vector<Type> bar;
    foo(bar);
  }

Аналогично:

 vector<Type> *vect = new vector<Type>; //allocates vect on heap and each of the Type will be allocated on stack

True, кроме последней части, с аналогичным примером счетчика:

  void foo(vector<Type> *vec) {
     // Can't be on stack - how would the stack "expand"
     // to make the extra space required between main and foo?
     vec->push_back(Type());
  }

  int main() {
    vector<Type> *bar = new vector<Type>;
    foo(bar);
  }

Для:

vector<Type*> vect; //vect will be on stack and Type* will be on heap. 

это правда, но обратите внимание, что указатели Type* будут в куче, но экземпляры Type, на которые они указывают, необязательно будут:

  int main() {
    vector<Type*> bar;
    Type foo;
    bar.push_back(&foo);
  }
20 голосов
/ 07 ноября 2011
vector<Type> vect; //allocates vect on stack and each of the Type (using std::allocator) also will be on the stack

Нет, vect будет в стеке, но массив, который он использует внутренне для хранения элементов, будет в куче.Элементы будут находиться в этом массиве.

vector<Type> *vect = new vector<Type>; //allocates vect on heap and each of the Type will be allocated on stack

Нет.Как и выше, только класс vector будет в куче.

vector<Type*> vect; //vect will be on stack and Type* will be on heap. 

vect будет в стеке, его элементы (указатели на Type) будутбыть в куче, и вы не можете сказать, где будут Type s, на которые указывают указатели.Может быть в стеке, может быть в куче, может быть в глобальных данных, может быть нигде (т. Е. NULL указатели).

Кстати, реализация может фактически хранить некоторые векторы (обычно небольшого размера).) в стеке целиком.Не то чтобы я знал о любой такой реализации, но она может.

3 голосов
/ 07 ноября 2011

Только это утверждение верно:

vector <Type*> vect; //vect will be on stack and Type* will be on heap.

Type* указатели размещаются в куче, поскольку количество указателей может изменяться динамически.

vect в этом случае размещается в стеке, поскольку вы определили его как локальную переменную стека.

...