Когда выделены векторы, они используют память в куче или стеке?

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

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?

Ответ 1

vector<Type> vect;

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

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

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

vector<Type*> vect;

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

Ответ 2

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

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

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

  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);
  }

Ответ 3

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, на который указывают указатели. Может быть в стеке, может быть в куче, может быть в глобальных данных, может быть нигде (т.е. указатели NULL).

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

Ответ 4

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

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

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

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

Ответ 5

вектор имеет внутренний allocator, который отвечает за выделение/освобождение памяти из heap для vector element. Поэтому независимо от того, как вы создаете вектор, его element всегда выделяется на heap. Что касается векторных метаданных, то это зависит от того, как вы их создадите.