Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
K&R 5.9-5.10
|
|||
|---|---|---|---|
|
#18+
Здравствуйте. 5.9 Приведён пример по возврату имени месяца по его номеру, я несколько переписал Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. У меня возникли следующие вопросы: 1. Как лучше, объявить массив: глобально, или внутри функции(у меня две функции потому глобально, у K&R внутри функции объявление) ? 2. Я знаю что массив закончится null, можно ли в случае если номер месяца вне предела выводить *(m+12). Мне кажется что это не хорошо. Но я не могу чётко объяснить себе почему. 3. Можно объявить массив внутри одной функции, но чтобы другая функция его видела ? 5.10 Сравниваются два массива Код: plaintext 1. 2. говорится о том что и то и другое двухмерные массивы, сравниваются объёмы выделенной памяти. И у меня возник вопрос который давно крутился у меня в голове. 4. f e, я объявил int a; но ещё не инициализировал. Выделилась ли память ? И такая-же ситуация с int a[5][5]. Память выделяется сразу после объявления ? а в случает с int* a[10]. В случае с указателями мне вообще хотелось бы самому выделять столько памяти, сколько потребуется, но чтобы в случае чего она была расширяемой(если не хватит, автоматически увеличилась). 5. Сколько памяти выделяет Windows/Unix программе которую я запускаю ? Как это узнать ? Как узнать диапазон адресов выделенных программе, этот диапазон будет адресовать локально относительно ОП или глобально, то есть printf("%p",&a) будет ли реальным адресом ОП. 6. Как из программы получить доступ к памяти которая данной программе не выделена. Возможно ли это ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2014, 04:39 |
|
||
|
K&R 5.9-5.10
|
|||
|---|---|---|---|
|
#18+
SashaMercuryУ меня возникли следующие вопросы: 1. Как лучше, объявить массив: глобально, или внутри функции(у меня две функции потому глобально, у K&R внутри функции объявление) ?Если со статичным массивом напрямую работает только одна функция, то лучше этот массив прятать в соответствующем модуле компиляции. А будет массив принадлежать видим только из самой функции, из модуля или глобальным это не так уж важно. Но обычно стараются ограничивать область видимости. А вдруг ты в другом модуле захочешь объявить другой массив monthes? И кстати, months а не monthes. SashaMercury2. Я знаю что массив закончится null, можно ли в случае если номер месяца вне предела выводить *(m+12). Мне кажется что это не хорошо. Но я не могу чётко объяснить себе почему.У тебя массив не заканчивается null'ом. *(m+12) в приведенном исходнике это выход за пределы массива со всеми вытекающими. SashaMercury3. Можно объявить массив внутри одной функции, но чтобы другая функция его видела ? Нет конечно. Читай учебник про области видимости. SashaMercuryСравниваются два массива Код: plaintext 1. 2. говорится о том что и то и другое двухмерные массивы, сравниваются объёмы выделенной памяти. И у меня возник вопрос который давно крутился у меня в голове.Любой двумерный массив это одномерный, любой одномерный это двумерный, трехмерный, и так-далее-мерный. Но в данном конкретном случае эти массивы очень разные и сравнивать их нельзя. SashaMercury4. f e, я объявил int a; но ещё не инициализировал. Выделилась ли память ? И такая-же ситуация с int a[5][5]. Память выделяется сразу после объявления ? а в случает с int* a[10]. Да, да, да, да и да. При появлении переменной в области видимости под нее сразу выделяется память на стеке. По выходу из области видимости эта память может быть использована другой переменной. SashaMercuryВ случае с указателями мне вообще хотелось бы самому выделять столько памяти, сколько потребуется, но чтобы в случае чего она была расширяемой(если не хватит, автоматически увеличилась). Автоматически никогда и ничего не выделяется. Но можно сделать свой тип данных типа структуры в которой будет храниться размер выделенной памяти и указатель на нее. А потом ты будешь обращаться к этому блоку памяти через специальный набор функций которые будут проверять сколько данных надо запомнить и сколько памяти уже выделено. Ну и при нужде запрашивать дополнительные куски памяти. Это уже существует во многих (практически во всех) серьезных библиотеках, но если ты сделаешь себе собственный менеджер памяти - никто протестовать не будет. SashaMercury5. Сколько памяти выделяет Windows/Unix программе которую я запускаю ? Как это узнать ? Как узнать диапазон адресов выделенных программе, этот диапазон будет адресовать локально относительно ОП или глобально, то есть printf("%p",&a) будет ли реальным адресом ОП. ээээ... Все не так как ты думаешь. Нет никаких локальных-глобальных-реальных адресов. Есть только память процесса и двухслойный менеджер виртуальной памяти. Это довольно сложная тема и объяснить ее на форуме не реально. Читай Таненбаума. На практике: считай что у твоей программы есть столько памяти сколько ты захочешь. Верхний предел конечно есть, но он плавающий и зависит от многих причин. SashaMercury6. Как из программы получить доступ к памяти которая данной программе не выделена. Возможно ли это ?Конечно можно! Но только один раз. Записываешь в указатель что угодно и обращаешься по нему. Тебя сразу же пристрелят, но факт злодейства уже совершен - ты обратился к памяти которая данной программе не выделена. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2014, 05:35 |
|
||
|
K&R 5.9-5.10
|
|||
|---|---|---|---|
|
#18+
Странно, но когда я пишу так: Код: plaintext 1. 2. 3. 4. то во время выполнения программа вылетает через 3 хода после выхода за пределы. А если как раньше, то всегда выводит null WhiteOwlКонечно можно! Но только один раз. Записываешь в указатель что угодно и обращаешься по нему. Тебя сразу же пристрелят, но факт злодейства уже совершен - ты обратился к памяти которая данной программе не выделена. Это интересно. То есть я могу написать программу которая обращается к одной ячейке памяти, и запустить эту программу в цикле например. А кто пристрелит ? Но я успею в одну ячейку памяти что-то или записать или прочитать ? WhiteOwlНет конечно. Читай учебник про области видимости. Мне казалось что это правило равносильно правилу того что все числа больше нуля в 3 классе. И я просто не знаю как обратиться к локальной переменной WhiteOwlДа, да, да, да и да. При появлении переменной в области видимости под нее сразу выделяется память на стеке. По выходу из области видимости эта память может быть использована другой переменной. Как она может быть использована ? То есть значение что я записал в ту ячейку может перезаписаться ?Или такое происходит только в том случае если переменная объявлена, но неинициализирована. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2014, 06:23 |
|
||
|
K&R 5.9-5.10
|
|||
|---|---|---|---|
|
#18+
SashaMercuryСтранно, но когда я пишу так: Код: plaintext 1. 2. 3. 4. то во время выполнения программа вылетает через 3 хода после выхода за пределы. А если как раньше, то всегда выводит null Этот код равнозначен такому Код: plaintext 1. 2. 3. 4. а изначально было Код: plaintext 1. конструкция (условие) ? значение1 : значение2; это упрощенный if. По другому так можно написать тоже самое Код: plaintext 1. 2. 3. 4. Понял в чем разница? SashaMercuryWhiteOwlКонечно можно! Но только один раз. Записываешь в указатель что угодно и обращаешься по нему. Тебя сразу же пристрелят, но факт злодейства уже совершен - ты обратился к памяти которая данной программе не выделена. Это интересно. То есть я могу написать программу которая обращается к одной ячейке памяти, и запустить эту программу в цикле например. А кто пристрелит ? Но я успею в одну ячейку памяти что-то или записать или прочитать ? Пристрелит ОС, т.е. твоя программа вылетит, записать/прочитать ничего ты не сможешь, т.к. по указанному адресу нет реальной памяти. Почему так в двух словах не расскажешь, как уже посоветовали: читай про устройство виртуальной памяти. Программа может не вылетать при обращении к несуществующей памяти: читай обработку исключений. Еще раз: не надо лезть за пределы того адресного пространства которое ты попросил. Попросил 12 элементов - не лезь в 13-й. Надо просто понимать что случайно ты туда можешь залезть, но последствия будут непредсказуемые, поэтому надо предусматривать некоторые самоограничения для защиты от подобных ситуаций. SashaMercuryWhiteOwlНет конечно. Читай учебник про области видимости. Мне казалось что это правило равносильно правилу того что все числа больше нуля в 3 классе. И я просто не знаю как обратиться к локальной переменной WhiteOwlДа, да, да, да и да. При появлении переменной в области видимости под нее сразу выделяется память на стеке. По выходу из области видимости эта память может быть использована другой переменной. Как она может быть использована ? То есть значение что я записал в ту ячейку может перезаписаться ?Или такое происходит только в том случае если переменная объявлена, но неинициализирована. Все на усмотрение компилятора. Пример Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Результат в релизе&i=0012FF7C &j=0012FF7C Результат в дебаге&i=0012FEF4 &j=0012FEF0 Схематично можно показать на таком примере Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. Когда заканчивается область видимости переменной i она уничтожается. Т.е. попытка где-то дальше к ней обратится вызовет ошибку компиляции, но реально она занимала какие-то 4 байта и эти байты никуда не исчезли, а просто стали не нужны, т.е. освободились и ничто не запрещает компилятору использовать их для другой переменной. Т.е. переменная j может использовать те же самые 4 байта памяти. Как следствие значение по указателю *pi нельзя использовать т.к. pi указывает на место где была i, а что там хранится после ее уничтожения - неизвестно. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2014, 08:59 |
|
||
|
K&R 5.9-5.10
|
|||
|---|---|---|---|
|
#18+
Dima_TПонял в чем разница? Между моим кодом и вашим ? По смыслу вроде одно и то же. Мне нравится конструкция Код: plaintext 1. , потому я её использую, она красивая :p Или она что-то упускает ? Dima_TКогда заканчивается область видимости переменной i она уничтожается. Т.е. попытка где-то дальше к ней обратится вызовет ошибку компиляции, но реально она занимала какие-то 4 байта и эти байты никуда не исчезли, а просто стали не нужны, т.е. освободились и ничто не запрещает компилятору использовать их для другой переменной. Т.е. переменная j может использовать те же самые 4 байта памяти. Как следствие значение по указателю *pi нельзя использовать т.к. pi указывает на место где была i, а что там хранится после ее уничтожения - неизвестно. Теперь понял все комментарии вкупе :) White Owl, Dima_T спасибо C: Я понял ) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2014, 10:02 |
|
||
|
K&R 5.9-5.10
|
|||
|---|---|---|---|
|
#18+
SashaMercuryИли она что-то упускает ? Ничего она не упускает. Пользуйся раз нравится :) Просто показалось что ты не понял ее смысл раз такой код написал SashaMercury Код: plaintext 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2014, 10:09 |
|
||
|
K&R 5.9-5.10
|
|||
|---|---|---|---|
|
#18+
аа.) нет, я этот код написал для того чтобы проверить что будет если я буду брать значения за выделенной компилятором памятью. Получился искусственный if, согласен ) Тоже красиво. Напоминает select * from t where id='1' or '1'='1' ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 17.02.2014, 13:04 |
|
||
|
|

start [/forum/topic.php?fid=57&fpage=64&tid=2019678]: |
0ms |
get settings: |
9ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
30ms |
get topic data: |
12ms |
get forum data: |
2ms |
get page messages: |
85ms |
get tp. blocked users: |
2ms |
| others: | 11ms |
| total: | 172ms |

| 0 / 0 |
