Когда векторы выделяются, они используют память в куче или стеке?
Все ли следующие утверждения верны?
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 ответа
vector<Type> vect;
выделит vector
информация о заголовке в стеке, но элементы в свободном хранилище ("куча").
vector<Type> *vect = new vector<Type>;
распределяет все по бесплатному магазину.
vector<Type*> vect;
выделит vector
в стеке и кучу указателей в бесплатном хранилище, но где эти точки определяются тем, как вы их используете (можно указать, например, элемент 0 на свободное хранилище и элемент 1 на стек).
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
указатели).
Кстати, реализация может фактически хранить некоторые векторы (как правило, небольшого размера) в стеке целиком. Не то чтобы я знал о такой реализации, но это возможно.
Предполагая реализацию, которая на самом деле имеет стек и кучу (стандарт 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
Правда, кроме последней части, с аналогичным контрпримером:
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);
}
Вектор имеет внутренний allocator
который отвечает за распределение / освобождение памяти от heap
для vector element
. Итак, как бы вы ни создавали вектор, егоelement
всегда выделяется на heap
. Что касается метаданных вектора, это зависит от того, как вы их создаете.
Только это утверждение верно:
vector <Type*> vect; //vect will be on stack and Type* will be on heap.
Type*
указатели размещаются в куче, потому что количество указателей может изменяться динамически.
vect
в этом случае размещается в стеке, потому что вы определили его как локальную переменную стека.