Когда выделены векторы, они используют память в куче или стеке?
Верны ли все следующие утверждения?
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
. Что касается векторных метаданных, то это зависит от того, как вы их создадите.