При создании массива в стеке
int stek_array [1000000];
произойдет переполнение стека, программа не скомпилируется, это понимаю.
При создании объекта
A* ob2 = new A();
ob2 будет находится в куче.
Вопрос следующий:
В каком типе памяти, стек или куча, будет тогда находится ob2.m? Ведь программа скомпилируется.
Раз программа скомилировалась, по идее ob.m будет находится в куче. В стеке массиву не хватило бы памяти. Но, это ведь тогда противоречит синтаксису определения массива в куче без оператора new.
Если все же ob.m находится в куче, надо ли в деструктор класса добавлять удаление массива?
delete m;
Есть ли в с++ или visual studio средства посмотреть тип памяти, в которой находится та или иная переменная?
Если создам объект в стеке A ob, а у класса "A" будет член int m [1000000]. В какой памяти тогда будет m? Ведь в стеке места ему не хватит
Код:
class A {
public:
int m[10000000];
A(){};
~A(){};
};
int main () {
int stek_array [1000000]; массив в стеке -> переполнение стека -> крах программы
int *heap_array = new int[1000000]; массив в куче, памяти хватает
delete heap_array; удалили массив из кучи
A ob; ob и ob.m в стеке -> переполнение стека -> крах программы
A* ob = new A(); вопрос касается этой строчки
delete ob;
return 0;
}
В куче - раз выделение памяти для объекта в куче, а массив - просто его часть.
Но, это ведь тогда противоречит синтаксису определения массива в куче без оператора new.
Почему? массив является частью объекта, который находится в куче, как единое целое. Посмотрите, чему равно sizeof(A)
. Вот эта память и выделяется для объекта - в данном случае она включает массив.
Нет, потому что это удаление выполняется автоматически - при удалении объекта. Вот если бы у вас был член int*m;
и в конструкторе для него выделялась бы память - тогда да, в деструкторе ее нужно было бы освобождать. Здесь же отдельного выделения памяти для массива нет.
Да по сути и так видно, что где :) Наверное, можно - по адресам или еще как-то...
Но я даже не могу представить ситуацию, когда объект выделен в куче, а какая-то его часть - в стеке (кроме извращения типа передаче указателя памяти, выделенной в стеке...).
"По-моему, так" (с) Пух
Механизм имеет много агрегатов. По вашему где находятся эти агрегаты, если механизм находится на Луне? Наверняка они, как часть механизма, вместе с ним на Луне. После уничтожения механизма, его агрегаты уничтожатся...
Если вы хотите выразить другое отношение, для этого существуют ассоциативность и наследование. Например, этот механизм может иметь и инструкцию, но инструкция вполне может находится не вместе с ним на Луне, а на Земле... Такое отношение(ассоциативность) выражать можно так.
class Mechanism {
Mechanism() : m(nullptr) {}
//...
private:
direction* m;
};
Если указатель нулевой, то нет инструкции. Если он указывает на инструкцию, находящийся в обьекте Земля, то независимо от того, где находится механизм, инструкция будет находится там, где находится Земля
В языке С++ нет такого понятия как "тип памяти". В С++ есть такое понятие, как "продолжительность хранения" (storage duration), которое говорит, как долго будет существовать память объекта, будет ли она освобождена автоматически и если будет, то когда.
В данном случае гарантируется, что память массива A::m
будет существовать ровно столько, сколько существует память охватывающего его объекта типа A
. Это фактически все, что вас должно беспокоить.
Практически же ваш массив является неотделимой встроенной частью объекта типа A
. Где расположен объект типа A
, там же расположен и массив A::m
.
В С++ нет такого понятия, как "синтаксис определения массива в куче". Невозможно определить что-то в куче. Определение можно предоставить только для именованного объекта, а объекты в куче не имеют имен. Объекты в куче создаются специальными выражениями (например, new-выражение), а не определениями.
При этом объявление нестатического члена класса не является определением вообще. Поэтому бессмысленно пытаться судить по этому объявлению о том, как и где будет выделяться память для объекта.
Нет, не надо. Вы не выполняли new-выражение, чтобы выделить память индивидуально для этого массива? Значит вам не нужно выполнять и delete-выражение для ее освобождения.
Ну наверное взглянув на адрес объекта и посмотрев на карту адресного пространства процесса можно определить, где именно располагается объект. Да, для всего этого существуют системно-зависимые и реализационно-зависимые средства.
Если "не хватит", значит вы и не сможете его создать. Вы же сами уже пришли к такому выводу в ходе своих экспериментов.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
В Python есть две функции: str и intЕсть ли возможность так переключаться между строкой и числом в C++? У меня есть a = 10
Как скрывать некоторые элементы TreeView и ListView?