Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.90/70: Рейтинг темы: голосов - 70, средняя оценка - 4.90
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143

Стек и куча: как все это работает?

21.02.2013, 23:13. Показов 14771. Ответов 58
Метки нет (Все метки)

Добрый вечер, подскажите пожалуйста хорошую литературу (сайты) по куче и стеку. Как оно все работает?
Насколько я понял все статические переменные лежат в стеке. К примеру в программе есть несколько переменных: а, б и с. Значит где-то должен хранится адрес каждой из них? Как осуществляется доступ к переменным?
Указатели (переменные) к примеру хранятся в стеке?
Вообщем вопрос один где про это все толково написано?
Спасибо за все хорошие источники...
2
Лучшие ответы (1)
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
21.02.2013, 23:13
Ответы с готовыми решениями:

Статика и динамика, стек и куча - что это
Помогите пожалуйста хорошей статьей какой нибудь, или советом :) интересуют такие банальные вопросы как - что такое куча, стек и где...

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

как все это в подробностях работает?
#include <iostream> #include<cstdlib> using namespace std; int main() { setlocale(LC_ALL, "Russian"); int i; int r; ...

58
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
22.02.2013, 00:37
Цитата Сообщение от Vourhey Посмотреть сообщение
Нет в случае со стеком она вообще не может быть свободной и занятой.
Сформулирую по другому: то есть, при выходе из for() переменная i подолжает существовать в стеке?
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
22.02.2013, 00:39
Цитата Сообщение от alsav22 Посмотреть сообщение
то есть, при выходе из for() переменная i подолжает существовать в стеке?
Конечно.

Добавлено через 1 минуту
Поменяй свой код на такой, если хочешь проверить:
C++
1
2
3
4
    int *a;
    for (int i = 0; i < 5; i++)
    {a = &i;}
   cout<<*a;
Добавлено через 38 секунд

Не по теме:

код не компилял, сорри, если где опечатался

1
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
22.02.2013, 00:40
Цитата Сообщение от Vourhey Посмотреть сообщение
Конечно.
И я могу с ней работать?
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
22.02.2013, 00:40
Цитата Сообщение от alsav22 Посмотреть сообщение
И я могу с ней работать?
Почему бы и нет.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
22.02.2013, 00:47
Тогда вопрос общего характера: что есть переменная? Область в памяти, или именованная область в памяти, или что ещё?
1
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
22.02.2013, 00:51
Цитата Сообщение от alsav22 Посмотреть сообщение
что есть переменная? Область в памяти или именованная область в памяти?

Не по теме:

"Переменная" - это вопрос субъективного восприятия :) так же, как и константы, ссылки и так далее. Кто, на каком уровне привык воспринимать, тот так и понимает.

1
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143
22.02.2013, 01:00  [ТС]
Цитата Сообщение от Vourhey Посмотреть сообщение
Тебе так же нужно знать смещение от начала массива в стеке, как в предыдущем примере
В общем, если в программе несколько статических переменных, то есть место где хранится адрес первого элемента стека, плюс дополнительная память где храниться смещение каждой переменной относительно адреса первой?
Для массивов есть смещение только для первого (нулевого) элемента, а с итым разбирается компилятор?

Добавлено через 5 минут
Не могу понять как работает стек...
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
22.02.2013, 01:02
http://dvo.sut.ru/libr/cvti/i618buz/8.htm
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
22.02.2013, 01:16
Цитата Сообщение от fuelcs Посмотреть сообщение
то есть место где хранится адрес первого элемента стека, плюс дополнительная память где храниться смещение каждой переменной относительно адреса первой?
Не совсем. Во первых, это зависит от компилятора, как будет вестись обращение к твоеим переменным, через указатель стека (ESP), или через адрес на начало локальных данных (часто в EBP хранится), или через что-нибудь еще. Стек растет от больших адресов к меньшим. Поэтому обращение к данным от их "начала" это операция "минус", а не "плюс".
Цитата Сообщение от fuelcs Посмотреть сообщение
Для массивов есть смещение только для первого (нулевого) элемента, а с итым разбирается компилятор?
Вопрос не понял.

Добавлено через 20 секунд
Цитата Сообщение от fuelcs Посмотреть сообщение
Не могу понять как работает стек...
Ща...

Добавлено через 2 минуты
Цитата Сообщение от fuelcs Посмотреть сообщение
Не могу понять как работает стек...
Может, те все-таки книжку почитать?

Добавлено через 1 минуту
Например, в этой книге: http://www.ozon.ru/context/detail/id/2631566/ все это описано.

Добавлено через 1 минуту
Вот пример кода сгенерированного компилятором для того примера с пустым циклом:
Assembler
1
2
3
4
5
6
7
8
9
    movl    $0, -4(%rbp)
    jmp .L2
.L3:
    addl    $1, -4(%rbp)
.L2:
    cmpl    $4, -4(%rbp)
    setle   %al
    testb   %al, %al
    jne .L3
Обращение через -4(%rbp) к этой переменной.
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
22.02.2013, 01:16
Цитата Сообщение от Vourhey Посмотреть сообщение
Кто, на каком уровне привык воспринимать, тот так и понимает.
Я привык, что у переменной есть имя.
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
22.02.2013, 01:18
Добавим код с указателем, который я там кидал выше и вот такой вариант возможен:
Assembler
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    movl    $0, -12(%rbp)
    jmp .L2
.L3:
    leaq    -12(%rbp), %rax
    movq    %rax, -8(%rbp)
    movl    -12(%rbp), %eax
    addl    $1, %eax
    movl    %eax, -12(%rbp)
.L2:
    movl    -12(%rbp), %eax
    cmpl    $4, %eax
    setle   %al
    testb   %al, %al
    jne .L3
-8(%rbp) - наш указатель
-12(%rbp) - это i

Добавлено через 1 минуту
Цитата Сообщение от alsav22 Посмотреть сообщение
Я привык, что у переменной есть имя.
Это ты написал, чтобы мы знали, как ты привык? )) окей, кто-нибудь это учтет переменная - языковое понятие. А понятие стека уже выходит за рамки языка. Значит и "переменную" уже обсуждать можно за рамками языка. То есть то, что она есть.
0
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143
22.02.2013, 01:18  [ТС]
Просто привык что информацию можно нагуглить, на википедии почитать...
Там написано про принцип LIFO, структура и все такое...
Предыдущий элемент указывает на следующий...
Но не могу понять (представить) как привязать конкретную переменную к определенному адресу...
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
22.02.2013, 01:54
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от fuelcs Посмотреть сообщение
Там написано про принцип LIFO, структура и все такое...
Потому что ты не то гуглишь. гугли "стековый фрейм", фрейм стека, cdecl, fastcall, регистры и их назначение (esp, в частности).
Просто "стек" - это еще и контейнер, но уже из другой области.

Добавлено через 33 минуты
Цитата Сообщение от fuelcs Посмотреть сообщение
В общем, если в программе несколько статических переменных то есть место где хранится адрес первого элемента стека,
Не статических. Автоматических. Статические хранятся в области данных, не на стеке. Что-то пропустил я часть твоего сообщения мимо глазных яблок...
3
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143
22.02.2013, 13:47  [ТС]
Цитата Сообщение от Vourhey Посмотреть сообщение
Статические хранятся в области данных, не на стеке.
Статические, имеется ввиду:
C++
1
static int a;
?
А переменная объявленная:
C++
1
int a;
является автоматической?
Еще вопрос, где хранятся глобальные переменные?

И в общем: код программы, статические переменные "хранятся в области данных", просто в оперативке (не в стеке не в куче)? Автоматические хранятся в стеке? Динамические в куче?

И на последок, переменные, объявленные через шаблоны, являются автоматическими и хранятся в стеке?
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
22.02.2013, 17:16
Цитата Сообщение от fuelcs Посмотреть сообщение
Еще вопрос, где хранятся глобальные переменные?
Отсюда: http://dvo.sut.ru/libr/cvti/i618buz/8.htm

"Область памяти, в которой размещается программа, делится на разделы по назначению и способам управления данными:

· сегмент кода используется для хранения кода программы – функций. Функции помещаются в сегмент кода на этапе компиляции программы и находятся там до завершения работы программы, поэтому все функции в C имеют глобальное время жизни и существуют в течение всего времени выполнения программы;

· статическая память (сегмент данных) предназначена для хранения переменных в течение всего времени выполнения программы. Если для переменной в какой-либо момент работы программы выделена память в сегменте данных, она там будет находиться до завершения работы программы, даже если эта переменная больше не нужна. По умолчанию в сегменте данных хранятся глобальные переменные;

· стек – это область памяти, в которой хранятся локальные переменные и параметры функций. При вызове функции ее параметры и локальные переменные помещаются в стек. Стек функционирует по принципу стакана – значение, помещенное в стек первым, оказывается на дне стека, в то время как последнее значение – на вершине стека. По завершении работы функции все данные, принадлежащие этой функции, удаляются из стека. Очистка стека начинается с вершины, т. е. со значений, помещенных в стек последними;

· динамическая память (куча) позволяет программисту управлять процессом выделения памяти под переменные и освобождением памяти. Переменные, размещаемые в динамической памяти, называются динамическими переменными."
Ещё можно здесь почитать: https://www.cyberforum.ru/blogs/18334/blog103.html
2
8 / 8 / 2
Регистрация: 14.01.2013
Сообщений: 141
22.02.2013, 19:27
alsav22, А что это
сегмент кода используется для хранения кода программы – функций. Функции помещаются в сегмент кода на этапе компиляции программы и находятся там до завершения работы программы, поэтому все функции в C имеют глобальное время жизни и существуют в течение всего времени выполнения программы;
Хм, а если глубже, то это нужно смотреть книги по архитектуре операционной системы?
0
5500 / 4895 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
22.02.2013, 19:57
Цитата Сообщение от mzarb Посмотреть сообщение
Хм, а если глубже, то это нужно смотреть книги по архитектуре операционной системы?
Может быть по ассемблеру. Там, насколько помню, тоже есть сегмент кода, сегмент данных и пр.

Добавлено через 5 минут
Код программы где-то же содержится? Это и есть сегмент кода. Данные отдельно - сегмент данных (статическая память). Стек отдельно. Динамическую память выделяет ОС. Как-то так.
2
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
22.02.2013, 22:41
Цитата Сообщение от mzarb Посмотреть сообщение
А что это
Почитай про формат исполняемых файлов. Узнаешь, что такое секции.
0
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143
23.02.2013, 17:43  [ТС]
Vourhey, Есть к Вам несколько вопросов...
Стек адресуется при помощи пары регистров SS:ESP. Регистр SS
(Stack Selector) содержит селектор сегмента стека при работе процессора
в защищенном режиме, ESP (Stack Pointer, указатель стека) - смещение
относительно базового адреса сегмента стека.
Мы выбираем с помощью SS сегмент памяти и ESP указывает на вершину стека внутри этого блока (сегмента памяти). Другими словами ESP (Stack Pointer, указатель стека) содержит не адрес (в понимании указатель) а только смещение относительно базового адреса?
То есть, в программе мы не работаем с физическим адресом, а с логическим?

И еще... Поскольку адресация в стеке идет от старших адресов к младшим (до 0x00000000), то размер стека ограничивается размерами сегмента памяти? Для x86 - 65536 байт? Или же стек может содержать в себе несколько сегментов памяти?

Добавлено через 2 минуты
Цитата Сообщение от Vourhey Посмотреть сообщение
-8(%rbp) - наш указатель
-12(%rbp) - это i
В ассемблере не силен... (%rbp)- это значение регистра ESP, а "-8" - это смещение относительно вершины стека?
0
~ Эврика! ~
 Аватар для OhMyGodSoLong
1258 / 1007 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
23.02.2013, 17:44
Закопайте сегментную адресацию обратно. Регистр SS оставлен в архитектуре исключительно для совместимости. В современных ОС он перменентно равен нулю, а ESP содержит полный адрес на все 32 бита.

Цитата Сообщение от fuelcs Посмотреть сообщение
В ассемблере не силен... (%rbp)- это значение регистра ESP, а "-8" - это смещение относительно вершины стека?
Да, только регистр всё же RBP (64-битный аналог ESP) и смещение относительно RBP — текущего стек-фрейма.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
23.02.2013, 17:44

стек и куча
Здравствуйте, уважаемые гуру! Подскажите, пожалуйста, как подобрать размер стека и кучи. Не понимаю, как узнать значения ZI(я...

Стек и куча
Всем привет. Только что вычитал из Tproger статью про стеки и кучи. https://tproger.ru/translations/programming-concepts-stack-and-heap/ ...

Стек и куча
Вроде разобрался с этими зверями, хочется уточнить некоторые моменты на понимание: физически они в ОЗУ, сначала сегмент кода программы,...

Стек и куча
Вот говорят, что для стека доступного места меньше, чем для кучи. И если есть много переменных большого размера, то лучше создавать их...

Тип данных String. Как это все работает?
Здравствуйте. Я только начал изучать этот замечательный язык, но столкнулся с проблемой --&gt; моим непониманием. при работе данной...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Новые блоги и статьи
Свет внутри себя
kumehtar 07.06.2026
Пусть это будет здесь lIs4oanZS9Y
Программа для com-порта
Uhbif79 05.06.2026
Всем привет, давно хотел изучить Qt, начинал, бросал, потом снова начинал. И сейчас вот смог написать свою первую программу. До этого имел опыт программирования микроконтроллеров, писал прошивки на. . .
Транскрипция 55-минутного видео через Whisper: WhisperDesktop облажался, спас Google Colab[
anaschu 01.06.2026
Понадобилось получить текст из свежезагруженного видео на YouTube. Казалось бы, задача на пять минут. Заняла полтора часа. Делюсь опытом — может кому пригодится последовательность решений. . . .
21 мат мед. Планы на развитие модели здравоСохранения
anaschu 01.06.2026
AnyLogic: план развития симуляционной модели рабочего коллектива — динамический абсентеизм, реальные данные, три сценария сравнения Продолжаю серию постов о дискретно-событийной модели рабочего. . .
20. Мат мед. Абсентеизм как отдельный тип простоя
anaschu 29.05.2026
Апдейт модели: исправленные баги, абсентеизм и новые механизмы Продолжаю развивать ранее описанную модель рабочего коллектива на AnyLogic. За последние несколько дней был проведён серьёзный. . .
19. здоровье, усталость и психотип работника влияют на производительность предприятия, и наоборот, производительность на здоровье, усталось и психотип
anaschu 28.05.2026
Дискретно-событийная модель рабочего коллектива на AnyLogic: здоровье, выгорание, психотипы и микростимуляция Привет, коллеги. Хочу поделиться итогами нескольких недель работы над симуляционной. . .
"Прокси" для последовательного порта
Eddy_Em 28.05.2026
Эту штуку написал я достаточно давно. Но сейчас вот понадобилось настроить датчик грозы, но при этом не отключать его от "метеодемона". Соответственно, надо запустить этот "прокси": метеодемон будет. . .
Рефакторинг программы уравнивания.
Massaraksh7 26.05.2026
Пример по предыдущей записи в блоге. Но, надо заметить, что, во-первых, там оптимизация не только математики, но и работы с базой данных, и с графами, а во-вторых, это ещё не всё.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru