![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Здравствуйте, форумчане.
Да, я уже поднимал эту тему, но, по правде сказать, в тот раз на некоторые вопросы ответа я не получил и решил, что книга это исправит. Но нет, не исправила. Вот накопившиеся вопросы: 1) Как я уже усвоил из предыдущей темы, в Windows (а, может, во всех ОС?) есть виртуальная память. На протяжении всего времени exe-файл работает с ней. Но я слышал вопросы о том, что некоторые программисты в результате операции std::cout << &a в функции main видели у себя на экране разные цифры, а значит, переменные при разных запусках занимали разные позиции. А значит, что в коде не прописаны адреса переменных даже в их виртуальной памяти. Так каким же образом программа получает эти неслучайные адреса? 2) Как работает программа? Моя гипотеза: в ОЗУ заносится бинарник, а далее программа подгружает из него все функции и далее работает по бинарнику, пошагово выполняя инструкции, которые в нем записаны и переходя по нужным меткам. 3) Физическая память. Я прочитал, что из-за ее фрагментации если не будет подходящего по длине пустого фрагмента, то будет отказано в доступе к памяти. Это в корне противоречит тому, как я думал. Я считал, что если мы создаем в виртуальной памяти массив, то каждая из его ячеек может располагаться в абсолютно произвольном месте. Это не так? 4) Насколько я понимаю, объекты также могут быть автоматическими, как и другие переменные. Однако мой товарищ сказал мне, что объекты всегда хранятся в динамической памяти, даже когда мы этого явно не задаем. Кто из нас прав? 5) Когда использовать автоматические переменные, а когда - динамические? Из предыдущей темы я узнал, что автоматические переменные гораздо быстрее удаляются, а к динамическим гораздо быстрее доступ. Выходит, что если мы часто обращаемся к переменной, то ее надо объявить как динамическую, а если мы ее используем мало, то нам гораздо выгоднее, чтоб она быстро удалилась? И почему объекты надо всегда хранить в динамической памяти? 6) Я прочитал, что классы в памяти не хранятся, но как же тогда мы можем использовать их методы подобным образом: name::method() ? 7) Правда ли, что слова private, public и protected перед членом класса в коде никаких изменений не делают и служат только для логики? 8) Бывают статические, динамические и автоматические переменные. Бывают ли еще какие-то, которые отличаются от этих по сроку жизни? 9) Я слышал, что структура и класс - одинаковые вещи за исключением тех мелочей, что поля у структуры по умолчанию декларируются как public, а у класса - private. Так ли это? 10) Когда создается автоматическая переменная? В том месте, где программист ее объявил в коде или при входе в блок кода? 11) Блок кода ведь тоже помещается в стек? Т. е. когда программа доходит в функции до блока кода ({блок}), то она создает новую ячейку в стеке, которая характеризует этот блок? 12) Объектный код - это по большей части исполняемый код? А линкер, выходит, просто подставляет нужные адреса переменным, и все? Если так, то в теории один и тот же линкер может отлинковать объектный код, сгенерированый разными компиляторами! В wiki просто прочел вот это:
Уважаемые программисты! Простите за огромное количество вопросов! Буду очень благодарен тому, кто захочет помочь! Это сообщение отредактировал(а) Hagrael - 17.8.2011, 12:40 |
|||
|
||||
boostcoder |
|
||||||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
это в какой теме вас в этом убедили? пруф пожалуйста. не уверен, но помоему, разницы в доступе нет для переменных на стеке и переменных в куче.. а это откуда взято? я очень редко беру на себя ручное управление памятью. не нужно искушать вероятность возникновения утечки ;)
не нужно путать код и данные. не уверен что правильно понял вопрос...
а сам-то как думаешь? разве в ассемблере есть такие ключевые слова? ;) да. но только в с++. |
||||||
|
|||||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
Hagrael |
|
||||||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
boostcoder, спасибо за ответ!
Но тогда вообще зачем использовать динамические переменные?
Действительно, я сейчас сам понял, что вопрос ошибочен.
ОК ![]() ОК, почитаю, чем они отличаются в других языках. Добавлено через 1 минуту и 15 секунд mes, т. е. на самом деле место в виртуальной памяти у переменной всегда одно и то же? Даже когда речь идет о динамической памяти? |
||||||
|
|||||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
динамические, я крайне редко использую. обычно обернутые в shared_ptr. mes, а что нужно понять из вашего примера? адрес переменной i одинаковый в двух вызовах. но функция не статическая. и переменная не статическая. поэтому мне кажется это просто случайность, или линкер очень грамотно понял ситуацию. или что? |
|||
|
||||
asmdzen |
|
|||
![]() ![]() ![]() Профиль Группа: Участник Сообщений: 345 Регистрация: 28.11.2010 Репутация: 3 Всего: 5 |
так разве не так и должно быть, при вызове функции место для переменной выделяется в стеке, когда f() вызывается из g() в стеке присутствует уже и адрес возврата из g() в main(), вот только не понятно куда девались еще 12 байт, или это какие то push esp? |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
ммм.. функция одна, стек один, если на стеке никого больше нет, то адрес автоматической переменной будет одним и тем же при каждом вызове.. а если есть то меняется, это и показывает пример.. |
|||
|
||||
boostcoder |
|
|||
![]() pattern`щик ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 5458 Регистрация: 1.4.2010 Репутация: 20 Всего: 110 |
mes, ну да.. понял.
|
|||
|
||||
asmdzen |
|
|||
![]() ![]() ![]() Профиль Группа: Участник Сообщений: 345 Регистрация: 28.11.2010 Репутация: 3 Всего: 5 |
||||
|
||||
Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Так что, может одна и та же переменная в коде при различных обстоятельствах иметь разные адреса?
|
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
rodnover |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
1, 2. Для загрузки файла в память используются первая часть файла exe (можно открыть в любом HEX редакторе и поковырять). На сайте wasm.ru, в принципе, есть много информации по структуре этого блока (PE-заголовок). В этом заголовке указаны базовый адрес программы, виртуальные адреса всех сегментов (кода, данных, стека) относительно базы и их размеры. На основе этих данных выполняется защита памяти (как, например, ошибки "память не может быть Read"). Да, забыл, в этом же заголовки прописываются все функции из внешних dll, подключенных статически. Во всей программе используются относительные адреса от базового адреса. Например, функция PrintMyStr() расположена на +0x100 байт от базового адреса. std::string my_str расположена +0x92 от базового адреса.
3. Управлением памятью осуществляют специальные менеджеры памяти, в задачи которых входит, выделение, освобождение страниц памяти, возможно, их дефрагментация и т.д... 4. Динамические объекты могут работать создаваться медленнее, в следствии каких-либо алгоритмов менеджера памяти, в то время, как на выделение объекта в стеке, фактически вызывают одну команду смещения указателя на верхушку стека. Но не думаю, что это замедление хоть сколько-то заметно. 5. Стек ограничен. В нем, помимо переменных хранится множество служебной информации (адреса возвратов из подпроцедур, блоки исключений). Наверно, всем встречалось сообщение об ошибке "Stack overflow" вызванное бесконечной рекурсией. Поэтому, в динамической памяти необходимо помещать крупные блоки информации. Это сообщение отредактировал(а) rodnover - 16.8.2011, 21:06 |
|||
|
||||
mes |
|
|||
любитель ![]() ![]() ![]() ![]() Профиль Группа: Участник Клуба Сообщений: 7954 Регистрация: 14.1.2006 Репутация: 79 Всего: 250 |
||||
|
||||
rodnover |
|
|||
![]() Бывалый ![]() Профиль Группа: Участник Сообщений: 223 Регистрация: 7.4.2009 Репутация: 2 Всего: 10 |
Ой да, конечно.
![]() Я думаю, там намного больше описок и неточностей. ;) Это сообщение отредактировал(а) rodnover - 16.8.2011, 21:05 |
|||
|
||||
Hagrael |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 143 Регистрация: 26.6.2011 Репутация: нет Всего: нет |
Он поставляется вместе с ОС или это нечто еще более низкоуровневое? А как программа узнает, какой адрес стоит занять? Ей дает об этом знать менеджер памяти? Базовый адрес - это адрес в виртуальной памяти? Если все остальные адреса указаны относительно него, а сам базовый адрес указан в файле, то одна и та же переменная обязана каждый раз иметь тот же адрес (сам я понимаю, что это невозможно, но все идет к этому). Т. е. объекты могут быть автоматическими, да? |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |