Какие основные виды памяти процесса существуют
Что проверяют
Понимаете ли вы, как устроено адресное пространство процесса и где физически оказываются ваши переменные. Следом обычно дают код и спрашивают, где лежит каждый объект и сколько он проживёт, или почему возврат указателя на локальную переменную ломает программу.
Как отвечать
Начните с того, что каждый процесс видит своё виртуальное адресное пространство, а ОС отображает его страницы на физическую память. Дальше пройдите по областям в типичной раскладке Linux и ELF:
- text: машинный код, страницы только для чтения и исполнения;
- rodata: константы и строковые литералы, тоже только чтение;
- data: глобальные и статические переменные с ненулевой инициализацией, значения лежат прямо в бинарнике;
- bss: глобальные и статические переменные, инициализированные нулём. В файле места не занимают, загрузчик выделяет обнулённые страницы;
- куча: динамическая память через
newиmalloc. Аллокатор берёт её у ОС черезbrkилиmmap, а glibc крупные блоки отдаёт отдельнымиmmap; - отображаемые области: разделяемые библиотеки, файлы через
mmap, блоки TLS для переменныхthread_local; - стек: у каждого потока свой. Кадр функции хранит локальные переменные и адрес возврата. В Linux у главного потока по умолчанию 8 МБ (
ulimit -s), в Windows 1 МБ.
Хорошо добавить язык стандарта: C++ говорит не о стеке и куче, а о длительности хранения. Automatic, static, thread и dynamic, и именно она определяет время жизни объекта. Про кучу сразу скажите, что голые new и delete в современном коде заменяют std::unique_ptr, std::make_shared и контейнеры.
Где спотыкаются
Говорят, что доступ к куче медленнее доступа к стеку. Память одна и та же, дорого само выделение через аллокатор, фрагментация и промахи кеша из-за разбросанных объектов.
Путают объект и его данные. Локальный std::vector лежит на стеке, а его элементы в куче; короткая std::string за счёт small string optimization может вообще не трогать кучу.
Считают строковый литерал изменяемым. Он в rodata, запись в него это неопределённое поведение, а преобразование литерала в char* без const с C++11 запрещено.