Q1
Java также хранит переменные в стеке, но экземпляры классов размещаются в куче. В C ++ вы можете свободно размещать экземпляры классов либо в стеке, либо в куче. Используя ключевое слово new
, вы выделяете экземпляр в куче.
Сегмент данных не является частью кучи, но выделяется при запуске процесса. Куча используется для динамического выделения памяти, когда сегмент данных статичен, а содержимое известно во время компиляции.
Сегмент BSS - это просто оптимизация, когда все данные, принадлежащие сегменту данных (например, строка, постоянные числа и т. Д.), Которые не инициализированы или инициализированы нулем, перемещаются в сегмент BSS. Сегмент данных должен быть встроен в исполняемый файл, и, перемещая «все нули» до конца, они могут быть удалены из исполняемого файла. Когда исполняемый файл загружен, сегмент BSS выделяется и инициализируется нулем, и компилятор все еще может знать адреса различных буферов, переменных и т. Д. Внутри сегмента BSS.
Q2
MyClass::number
хранится там, где размещен экземпляр класса MyClass
. Это может быть либо в куче, либо в стеке. Обратите внимание, что в Q3 a
указывает на экземпляр MyClass
, выделенный в куче, в то время как localObj
выделяется в стеке. Таким образом, a->number
находится в куче, а localObj.number
находится в стеке.
Поскольку MyClass::number
является переменной экземпляра, вы не можете назначить ее следующим образом:
MyClass::number = 100;
Однако вы можете назначить MyClass::counter
как статическое (за исключением того, что оно является приватным):
MyClass::counter = 100;
Q3
При вызове doHello
переменная localObj
(в main
) передается по ссылке. Переменная localObj
в doHello
ссылается на эту переменную в стеке. Если вы измените его, изменения будут сохранены в стеке, где выделено localObj
в main
.
Когда вы вызываете doHelloAgain
, переменная localObj
(в main
) копируется в стек. Внутри doHelloAgain
переменная localObj
размещается в стеке и существует только на время вызова.