12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143
1

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

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

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

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

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

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

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

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

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

Не по теме:

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

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

Не по теме:

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

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

Добавлено через 5 минут
Не могу понять как работает стек...
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
22.02.2013, 01:02 28
http://dvo.sut.ru/libr/cvti/i618buz/8.htm
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
22.02.2013, 01:16 29
Цитата Сообщение от 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
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
22.02.2013, 01:16 30
Цитата Сообщение от Vourhey Посмотреть сообщение
Кто, на каком уровне привык воспринимать, тот так и понимает.
Я привык, что у переменной есть имя.
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
22.02.2013, 01:18 31
Добавим код с указателем, который я там кидал выше и вот такой вариант возможен:
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  [ТС] 32
Просто привык что информацию можно нагуглить, на википедии почитать...
Там написано про принцип LIFO, структура и все такое...
Предыдущий элемент указывает на следующий...
Но не могу понять (представить) как привязать конкретную переменную к определенному адресу...
0
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
22.02.2013, 01:54 33
Лучший ответ Сообщение было отмечено как решение

Решение

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

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

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

И на последок, переменные, объявленные через шаблоны, являются автоматическими и хранятся в стеке?
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
22.02.2013, 17:16 35
Цитата Сообщение от 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 36
alsav22, А что это
сегмент кода используется для хранения кода программы – функций. Функции помещаются в сегмент кода на этапе компиляции программы и находятся там до завершения работы программы, поэтому все функции в C имеют глобальное время жизни и существуют в течение всего времени выполнения программы;
Хм, а если глубже, то это нужно смотреть книги по архитектуре операционной системы?
0
5498 / 4893 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
22.02.2013, 19:57 37
Цитата Сообщение от mzarb Посмотреть сообщение
Хм, а если глубже, то это нужно смотреть книги по архитектуре операционной системы?
Может быть по ассемблеру. Там, насколько помню, тоже есть сегмент кода, сегмент данных и пр.

Добавлено через 5 минут
Код программы где-то же содержится? Это и есть сегмент кода. Данные отдельно - сегмент данных (статическая память). Стек отдельно. Динамическую память выделяет ОС. Как-то так.
2
Почетный модератор
7393 / 2639 / 281
Регистрация: 29.07.2006
Сообщений: 13,696
22.02.2013, 22:41 38
Цитата Сообщение от mzarb Посмотреть сообщение
А что это
Почитай про формат исполняемых файлов. Узнаешь, что такое секции.
0
12 / 12 / 2
Регистрация: 23.01.2013
Сообщений: 143
23.02.2013, 17:43  [ТС] 39
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
~ Эврика! ~
1256 / 1005 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
23.02.2013, 17:44 40
Закопайте сегментную адресацию обратно. Регистр SS оставлен в архитектуре исключительно для совместимости. В современных ОС он перменентно равен нулю, а ESP содержит полный адрес на все 32 бита.

Цитата Сообщение от fuelcs Посмотреть сообщение
В ассемблере не силен... (%rbp)- это значение регистра ESP, а "-8" - это смещение относительно вершины стека?
Да, только регистр всё же RBP (64-битный аналог ESP) и смещение относительно RBP — текущего стек-фрейма.
1
23.02.2013, 17:44
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
23.02.2013, 17:44
Помогаю со студенческими работами здесь

Стек и куча
Всем привет. Только что вычитал из Tproger статью про стеки и кучи....

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

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

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


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru