Где в памяти хранятся имена или типы переменных/ссылок для переменных стека/кучи?

Я думаю, что понимаю основную разницу между стеком и кучей.

В следующей программе в куче создается объект размера n. Указатель p, ссылающийся на этот софа или безымянный объект, создается в стеке, где он занимает 4 байта (по крайней мере, в моей системе). Если я правильно понял, поскольку ссылки не используют дополнительную память, дополнительная память не выделяется (за исключением, может быть, int, возвращаемого main() в стеке).

Class Object;  // n bytes

int main() {
    Object* p = new Object();
    Object& r = *p;
    // ...
}

Тем не менее, управление памятью еще не до конца понятно:

1) где хранятся имена p и r? Оба они являются локальными именами, поэтому я полагаю, что они также должны быть в стеке? Не требует ли это дополнительной памяти для хранения привязки между именем переменной и той частью памяти, на которую оно ссылается?

2) где хранится тип указателя? Указатель занимает всего 4 байта в стеке, что (я думаю) является точным размером для хранения адреса памяти. Как компьютер узнает, какой тип можно найти по этому адресу?

3) аналогично (2), объекту в куче требуется n байт памяти и единственная (прямая) ссылка на него 0 байт. Где хранится тип этого объекта, чтобы при использовании r он знал, какой это тип?

4) Я понял, что скомпилированная программа также находится где-то в памяти, чтобы управлять ее выполнением. Это в стеке или в куче, или это еще одна часть памяти?


person mr_T    schedule 26.11.2014    source источник
comment
Вас интересует тип p или *p ? Потому что с производными классами p также может указывать на подобъект базового класса внутри более крупного объекта.   -  person MSalters    schedule 26.11.2014


Ответы (3)


где хранятся имена p и r?

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

Они могут быть доступны в специальном разделе отладки файла программы, чтобы позволить отладчику отображать значения переменных.

где хранится тип указателя?

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

Где хранится тип этого объекта?

Если тип полиморфный (т.е. если это тип класса с хотя бы одной виртуальной функцией), то будут некоторые статические данные, хранящиеся в неуказанном месте, к которым вы не можете получить прямой доступ, для описания тип. Будет достаточно данных для поддержки вызовов виртуальных функций (обычно это таблица указателей на окончательные переопределения) и RTTI (спецификация структуры наследования для использования dynamic_cast и структура type_info, доступная через typeid).

В противном случае вся информация о типе является статической.

Находится ли [скомпилированная программа] в стеке или в куче, или это еще одна часть памяти?

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

person Mike Seymour    schedule 26.11.2014
comment
Ну, есть RTTI — информация о типе во время выполнения, потому что не все типы полностью статичны. ОО допускает полиморфизм. Но сами указатели никогда не бывают полиморфными. - person MSalters; 26.11.2014
comment
@MSalters: Действительно, я несколько упростил. - person Mike Seymour; 26.11.2014
comment
При повторном прочтении я думаю, что вопрос неоднозначен сам по себе. Он также задается вопросом, какой тип можно найти по этому адресу?, то есть он определенно задается вопросом об объекте, на который он указывает. И тогда RTTI точно актуален. Мы не знаем, является ли Object полиморфным. - person MSalters; 26.11.2014
comment
@MSalters: Хороший вопрос, возможно, на вопрос 3 нужен собственный ответ. - person Mike Seymour; 26.11.2014

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

Как реализуются ссылки, не указано в стандарте C++, но большинство компиляторов реализуют их так же, как указатели, поэтому в неоптимизированном коде, вероятно, будет еще 4 байта (в вашей системе) для r....

где хранятся имена p и r

здесь хранится тип указателя?

Где хранится тип [r]

Они существуют внутри самого компилятора во время его работы и, возможно, в некоторой информации о символах отладки, помещаемой в сгенерированные объекты/библиотеки/программу, чтобы помочь в интерактивной отладке, если вы используете, например. Опция g++ -g GCC, но они не сохраняются и не доступны через обычные операторы программы C++.

Я понял, что скомпилированная программа также находится где-то в памяти, чтобы направлять ее выполнение. Это в стеке или в куче, или это еще одна часть памяти?

Скомпилированная программа представляет собой набор двоичных данных и кодов операций (чисел) машинного кода, которые операционная система знает, как загружать и запрашивать у ЦП для интерпретации и выполнения. Эти данные для этого обычно находятся не в стеке и не в куче, а в смеси неинициализированных данных, инициализированных данных и сегментов/областей кода, которые организует операционная система.

person Tony Delroy    schedule 26.11.2014

Компьютеры никогда не знают p и r. Имена переменных используются для улучшения читаемости в языках высокого уровня. Например, вы можете получить ассемблерный код через

gcc -S -c code.c

В code.s вообще нет p и r

person Min Fu    schedule 26.11.2014