Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.79/24: Рейтинг темы: голосов - 24, средняя оценка - 4.79
Scrooge McDuck
Заблокирован
1

Переменные в стеке. Где хранятся? Как обрабатываются? Есть ли программный стек или только стек процессора?

02.10.2014, 21:59. Просмотров 4538. Ответов 36
Метки нет (Все метки)

Есть у меня пробелы в познаниях, хотел бы их устранить.
1. Что такое стек в самом языке С++ ?
2. В какой памяти он хранится и почему они маленький?
3. Вот когда говорят "переменная создаётся в стеке", где конкретное она создаётся?

На сколько я понимаю, каждая функция в кидает все свои аргументы в стек по LIFO (он же вроде stdcall), а когда идёт возврат - всё оттуда в обратном порядке возвращается.

Да не суть Я знаю, что есть стек процессора, ну в частности регистр EBP служит для определения текущего активного кадра стека, а что такое стек в С++ и как он связан с ассемблером и как он связан с процессором? В какой памяти храниться и как обрабатывается? Может стек С++ - это просто как бы просто работа с регистрами процессора? То есть аргументы функции просто в регистры засовываются, но тогда сколько ж регистров надо ... или там суётся в виртуальные регистры, так же как и для каждого потока есть свой набор регистров. Или же стек хранится в быстрой памяти процессора L2 / L3 ?

Даже не знаю как спросить, чтоб развести муть в голове... наверное так:
Как работает стек на уровне C++ / Assembler / Процессор ?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
02.10.2014, 21:59
Ответы с готовыми решениями:

Пронумерировать стек. Ошыбка в стеке
Никак не пойму почему програма ничево не выводит на функции renumber,после...

Стек содержит целые числа, удвоить вхождение нуля в стеке
Стек содержит целые числа, удвоить вхождение нуля в стеке

Стек на массиве (выводит значение даже при пустом стеке)
Здравствуйте, есть код со стеком, вопрос касательно метода класса,а точнее о...

Память. Стек или куча - есть ли преимущества одного кода над другим?
Здравствуйте, хотел спросить в чем различия. В чем тут недостатки и...

Дан стек, заполненный целыми числами. Поменять в данном стеке содержимое вершины и дна
Дан стек, заполненный целыми числами. Поменять в данном стеке содержимое...

36
Renji
2105 / 1545 / 471
Регистрация: 05.06.2014
Сообщений: 4,484
02.10.2014, 22:07 2
Цитата Сообщение от Scrooge McDuck Посмотреть сообщение
1. Что такое стек в самом языке С++ ?
2. В какой памяти он хранится и почему они маленький?
3. Вот когда говорят "переменная создаётся в стеке", где конкретное она создаётся?
1) Тоже самое что в ассемблере. Если, конечно, мы не про std::stack.
2) Потому что стек жрет адресное пространство перманентно, а динамическая память - только когда потребуется. А программистов жаба душит. Впрочем, вам никто не мешает залезть в настройки компилятора и прописать там гигабайт под стек. Хотя, это не по фэншую.
3) В стеке. Который из ассемблера. Или в регистрах, если так захочется оптимизатору.
0
Scrooge McDuck
Заблокирован
02.10.2014, 22:32  [ТС] 3
То есть стек - это вся та же память из кучи грубо говоря? Просто все переменные, объявленные статические, помещаются в кусок памяти определённого размера, который аллоцируется одиножды при старте программы и освобождается при выходе, так что ли? А почему говорят, что типа работ со стеком быстрее ?
1
Renji
2105 / 1545 / 471
Регистрация: 05.06.2014
Сообщений: 4,484
03.10.2014, 00:22 4
Цитата Сообщение от Scrooge McDuck Посмотреть сообщение
То есть стек - это вся та же память из кучи грубо говоря? Просто все переменные, объявленные статические, помещаются в кусок памяти определённого размера, который аллоцируется одиножды при старте программы и освобождается при выходе, так что ли? А почему говорят, что типа работ со стеком быстрее ?
Выделение памяти из кучи - берется таблица "список всех кусков памяти которые никто еще не захапал". В этой таблице ищется свободная область подходящего размера и используется под данные. Таблица большая, поиск не быстрый.

Выделение памяти из стека - берется непрерывный кусок памяти с указателем "захапано до этого места". В "до этого места" размещаются нужные данные, а указатель смещается. Так как ничего искать не надо, выделение памяти происходит почти мгновенно. Но ценой скорости становится примитивность алгоритма выделения/освобождения памяти. Например, удалить кусок из середины стека нельзя.

Статическое выделение памяти - все данные размещаются по заранее известным адресам. Искать место под них не надо.
3
Scrooge McDuck
Заблокирован
03.10.2014, 08:55  [ТС] 5
Цитата Сообщение от Renji Посмотреть сообщение
Выделение памяти из кучи
Нет, ну а если я алоцировал кусочеГ и с ним работаю, то есть не каждую секунду что - то заново пытаюсь захапать, а просто работаю с уже выделенным большим кусочком, скорость же будет такая же, как и на стеке, верно ?

Цитата Сообщение от Renji Посмотреть сообщение
Но ценой скорости становится примитивность алгоритма выделения/освобождения памяти. Например, удалить кусок из середины стека нельзя.
Ну вот я пишу обычный код ничего не подразумевая про стек, я его использую неявно или нет? Или чтоб работать с этим хитрым LIFO кусочком, надо какие - то спец операторы использовать?

Цитата Сообщение от Renji Посмотреть сообщение
Статическое выделение памяти - все данные размещаются по заранее известным адресам
Память под стек не статический выделяется ?

Добавлено через 3 минуты
Цитата Сообщение от Renji Посмотреть сообщение
берется непрерывный кусок памяти с указателем "захапано до этого места"
Ну то есть это ж простое выделение куска памяти определённого размера и последующая работа с ним, так что ли? То есть если я алоцирую при старте программы гигабайт памяти (а new вроде и хапает непрерывный кусочек) и просто с ним каким - то образом работаю, не удаляя его, а просто предоставля указатель своему собственному менеджеру памяти, когда тот попросит, это ж и будет грубо говоря стек ?
0
alsav22
5442 / 4837 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.10.2014, 10:36 6
Цитата Сообщение от Scrooge McDuck Посмотреть сообщение
Ну вот я пишу обычный код ничего не подразумевая про стек, я его использую неявно или нет? Или чтоб работать с этим хитрым LIFO кусочком, надо какие - то спец операторы использовать?
Используешь, не используешь - для каждой программы (потока) выделяется (на этапе компиляции) память с автоматическим классом хранения. Размер по умолчанию, или устанавливается в настройках компилятора. Хранятся локальные переменные, параметры передаются, при вызове функций, адреса возврата из функций.
1
Scrooge McDuck
Заблокирован
03.10.2014, 11:28  [ТС] 7
Цитата Сообщение от alsav22 Посмотреть сообщение
Хранятся локальные переменные, параметры передаются, при вызове функций, адреса возврата из функций.
Ну в общем понял, я это и так знал. Стек - ерунда ) Я думал, там что то архи крутое
0
alsav22
5442 / 4837 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.10.2014, 11:32 8
Цитата Сообщение от Scrooge McDuck Посмотреть сообщение
я это и так знал.
И я думаю, что занешь. Но зачем тогда такие вопросы?
Цитата Сообщение от Scrooge McDuck Посмотреть сообщение
Ну вот я пишу обычный код ничего не подразумевая про стек, я его использую неявно или нет?
0
Scrooge McDuck
Заблокирован
03.10.2014, 11:42  [ТС] 9
Цитата Сообщение от alsav22 Посмотреть сообщение
И я думаю, что занешь. Но зачем тогда такие вопросы?
Да я самоучка, я никогда не учился на программиста, всю инфу искал сам и изучал По этому иногда в азах и всплывают пробелы
0
Tulosba
:)
Эксперт С++
4749 / 3243 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.10.2014, 11:45 10
Цитата Сообщение от alsav22 Посмотреть сообщение
для каждой программы (потока) выделяется (на этапе компиляции) память
Учитывая, что кол-во потоков в программе заранее не известно, память не может выделяться на этапе компиляции.
Цитата Сообщение от Scrooge McDuck Посмотреть сообщение
это ж и будет грубо говоря стек ?
Нет. Это будет скорее пул памяти. Стек подразумевает наличие указателя вершины и невозможность удалять из середины.
0
Scrooge McDuck
Заблокирован
03.10.2014, 11:58  [ТС] 11
Цитата Сообщение от Tulosba Посмотреть сообщение
Стек подразумевает наличие указателя вершины и невозможность удалять из середины.
Ну так а в какой памяти он хранить? Учитывая, что я могу его размер произвольно задать - явно не в L2/L3 процессора
И когда память под него выделяется?
0
Tulosba
:)
Эксперт С++
4749 / 3243 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.10.2014, 12:05 12
Цитата Сообщение от Scrooge McDuck Посмотреть сообщение
Ну так а в какой памяти он хранить?
Скорее всего в ОЗУ. Но это лежит на совести ОС и железа. Может и на диск скинуть (ты же в курсе, что такое виртуальная память и файл подкачки?).
Цитата Сообщение от Scrooge McDuck Посмотреть сообщение
И когда память под него выделяется?
При создании потока.
0
Scrooge McDuck
Заблокирован
03.10.2014, 12:25  [ТС] 13
Цитата Сообщение от Tulosba Посмотреть сообщение
ы же в курсе, что такое виртуальная память и файл подкачки?
В курсе, но если б память стека свопнулась на хард, о какой скорости работы программы тогда вообще могла быть речь
Я думаю, тут надо ждать коммента Убеждённого
По идее у процессора есть свой стек комманд, а вот как работает стек С++ - хз, пока так и не понял, точнее как - то это понятно, LIFO труляля, а как физический он работает и где хранится = хз
0
alsav22
5442 / 4837 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.10.2014, 12:28 14
Цитата Сообщение от Tulosba Посмотреть сообщение
Учитывая, что кол-во потоков в программе заранее не известно, память не может выделяться на этапе компиляции.
Зачем тогда размер статически создаваемого массива должен быть известен на этапе компиляции?
0
Scrooge McDuck
Заблокирован
03.10.2014, 12:39  [ТС] 15
Цитата Сообщение от alsav22 Посмотреть сообщение
Учитывая, что кол-во потоков в программе заранее не известно, память не может выделяться на этапе компиляции.
Я попробую продолжить мысль. У каждого потока свой набор виртуальных регистров, работа с которыми проецируется в порядке очереди на физические регистры процессора. По этому скорее всего размер стека может быть любым, вне зависимости от того, сколько есть быстрой памяти в самом процессоре, просто если стек большой - работа с физическим стеком процессора будет идти частями и медленно, ХОТЯ! скорее всего я горожу чушь и стек команд физического процессора не имеет ни какого отношения к программному стеку С++
1
Tulosba
:)
Эксперт С++
4749 / 3243 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.10.2014, 12:57 16
Цитата Сообщение от Scrooge McDuck Посмотреть сообщение
а как физический он работает и где хранится = хз
Просто ты мечешься между уровнями представления, что такое память, отсюда и путаница.
На уровне языка нет никаких L2/L3 и прочего, есть различная продолжительность жизни переменных (см. 3.7 Storage duration). В частности различают 4 типа:
1. static storage duration
2. thread storage duration
3. automatic storage duration
4. dynamic storage duration
В общем случае, тип 3 - это и есть стековые переменные.
Вот тут ещё можешь почитать: http://rsdn.ru/article/cpp/ObjectsAndPointers.xml#EVPAC
Цитата Сообщение от alsav22 Посмотреть сообщение
Зачем тогда размер статически создаваемого массива должен быть известен на этапе компиляции?
Как это связано с обсуждаемой проблемой? К тому же, gcc ведь разрешает создавать VLA-массивы на стеке.

Добавлено через 1 минуту
Цитата Сообщение от Scrooge McDuck Посмотреть сообщение
скорее всего я горожу чушь и стек команд физического процессора не имеет ни какого отношения к программному стеку С++
вот это точно
1
alsav22
5442 / 4837 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.10.2014, 13:15 17
Цитата Сообщение от Tulosba Посмотреть сообщение
Как это связано с обсуждаемой проблемой?
Размер должен быть известен, чтобы память на стеке выделить? Или для чего?
Цитата Сообщение от Tulosba Посмотреть сообщение
К тому же, gcc ведь разрешает создавать VLA-массивы на стеке.
VLA - это не стандарт, что об этом говорить?
0
Tulosba
:)
Эксперт С++
4749 / 3243 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.10.2014, 14:00 18
alsav22, давай по порядку. У каждого потока свой стек. Количество потоков не известно на этапе компиляции, стало быть и выделяться память для стека потока не может на этом этапе. Можно конечно предложить выделить память сразу под максимальное кол-во потоков процесса, но это не эффективно.
Немного другой момент - размер этого стека по умолчанию. Как задавать для VS можно посмотреть например тут. Но даже этот размер можно изменять при создании конкретного потока.
Цитата Сообщение от alsav22 Посмотреть сообщение
VLA - это не стандарт, что об этом говорить?
В данном конкретном случае дело не в Стандарте, а в возможности как таковой. Возможность есть, значит этапом компиляции дело не ограничивается. Но VLA ограничивается размером стека. Как не сложно догадаться.
0
alsav22
5442 / 4837 / 831
Регистрация: 04.06.2011
Сообщений: 13,587
03.10.2014, 14:05 19
Цитата Сообщение от Tulosba Посмотреть сообщение
давай по порядку. У каждого потока свой стек. Количество потоков не известно на этапе компиляции, стало быть и выделяться память для стека потока не может на этом этапе.
Ты на вопрос можешь ответить?
Цитата Сообщение от alsav22 Посмотреть сообщение
Зачем тогда размер статически создаваемого массива должен быть известен на этапе компиляции?
0
Tulosba
:)
Эксперт С++
4749 / 3243 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
03.10.2014, 14:29 20
Цитата Сообщение от alsav22 Посмотреть сообщение
Ты на вопрос можешь ответить?
Цитата Сообщение от alsav22 Посмотреть сообщение
Зачем тогда размер статически создаваемого массива должен быть известен на этапе компиляции?
Я уже отвечал на этот вопрос.
Цитата Сообщение от Tulosba Посмотреть сообщение
gcc ведь разрешает создавать VLA-массивы на стеке.
Если ты хочешь знать, почему Стандарт требует известного размера массива на этапе компиляции, то я вряд ли дам тебе точный ответ. Но думаю, это возникло из-за нежелания переводить потенциальную ошибку выделения памяти из этапа компиляции в этап выполнения.
1
03.10.2014, 14:29
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
03.10.2014, 14:29

Создать стек из вещественных чисел; найти максимальный элемент в стеке; организовать просмотр данных стека
Создать стек из вещественных чисел. Определить максимальный элемент в стеке....

при работе рекурсивной функции заканчивается стек и программа соответственно; как сделать так, чтобы она писала "стек закончился"?
Сабж g++ 4.5.0

Используя стек, описать функцию проверяющую, является ли стек пустым
Используя стек, описать функцию проверяющую, является ли стек пустым


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru