Вызовы ленивых программистов: — КиберПедия 

Таксономические единицы (категории) растений: Каждая система классификации состоит из определённых соподчиненных друг другу...

Общие условия выбора системы дренажа: Система дренажа выбирается в зависимости от характера защищаемого...

Вызовы ленивых программистов:

2021-01-29 97
Вызовы ленивых программистов: 0.00 из 5.00 0 оценок
Заказать работу

 

«Опасность, Билл Робинсон! Опасность!»

‑ Робот ‑

 

Есть еще одна дополнительная функция выделения памяти, о которой вам нужно знать. Мы обсуждаем ее лишь для того, чтобы вы поняли ее, когда увидите, но не следует использовать ее в новых программах! Эта функция называется; она объявлена следующим образом:

 

 

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

На первый взгляд, выглядит чем‑то типа панацеи для программистов, можно выделять память, о которой можно вовсе не беспокоиться. Подобно Темной Стороне Силы, это, конечно, привлекает. И подобным же образом этого нужно избегать по следующим причинам:

• Функция не является стандартной; она не включена ни в какой стандарт, ни в ISO, ни в С или POSIX.

• Функция не переносима. Хотя она существует на многих системах Unix и GNU/Linux, она не существует на не‑Unix системах. Это проблема, поскольку код часто должен быть многоплатформенным, выходя за пределы просто Linux и Unix.

• На некоторых системах невозможно даже реализовать. Весь мир не является ни процессором Intel x86, ни GCC.

• Цитируя справку[45] (добавлено выделение): «Функция зависит от машины и от компилятора. На многих системах ее реализация ошибочна. Ее использование не рекомендуется».

• Снова цитируя справку: «На многих системах не может быть использована внутри списка аргументов вызова функции, поскольку резервируемая в стеке при помощи память оказалась бы в середине стека в пространстве для аргументов функции».

• Она потворствует неряшливому программированию. Тщательная и корректная работа с памятью не сложна; вам просто нужно подумать о том, что вы делаете, и планировать заранее.

GCC обычно использует встроенную версию функции, которая действует с использованием внутритекстового (inline) кода. В результате есть другие последствия. Снова цитируя справку:

 

Факт, что код является внутритекстовым (inline), означает, что невозможно получить адрес этой функции или изменить ее поведение путем компоновки с другой библиотекой.

Внутритекстовый код часто состоит из одной инструкции, подгоняющей указатель стека, и не проверяет переполнение стека. Поэтому нет возврата при ошибке.

 

Справочная страница не углубляется в описание проблемы со встроенной GCC. Если есть переполнение стека, возвращаемое значение является мусором. И у вас нет способа сообщить об этом! Это упущение делает невозможным использование GCC в устойчивом коде.

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

 

Исследование адресного пространства

 

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

 

Эта программа распечатывает местонахождение двух функций и (строки 22–23). Затем она показывает, как стек растет вниз, позволяя (строки 51–63) распечатать адреса последовательных экземпляров ее локальной переменной. (намеренно объявлена как, чтобы подчеркнуть, что она находится в стеке.) Затем она показывает расположение памяти, выделенной с помощью (строки 28–32). В заключение она печатает местоположение переменных данных и BSS (строки 34–38), а затем памяти, выделенной непосредственно через (строки 40–48). Вот результаты запуска программы на системе Intel GNU/Linux:

ch03‑memaddr

 

 

Резюме

 

• У каждой программы Linux и (Unix) есть различные области памяти. Они хранятся в разных частях файла исполняемой программы на диске. Некоторые из секций загружаются при запуске программы в одну и ту же область памяти. Все запушенные экземпляры одной и той же программы разделяют исполняемый код (сегмент текста). Программа показывает размеры различных областей переместимых объектных файлов и полностью скомпонованных исполняемых файлов.

• В адресном пространстве запушенной программы могут быть дыры, а размер адресного пространства может изменяться при выделении и освобождении памяти. На современных системах адрес 0 не является частью адресного пространства, поэтому не пытайтесь разыменовывать указатели.

• На уровне языка С память выделяется с помощью одной из функций, или. Память освобождается с помощью. (Хотя с помощью можно делать все, использование ее таким образом не рекомендуется.) Освобожденная память обычно не удаляется из адресного пространства; вместо этого она используется повторно при последующих выделениях.

• Необходимо предпринять чрезвычайные меры осторожности в следующих случаях

• освобождать лишь память, выделенную с помощью соответствующих процедур,

• освобождать память один и только один раз,

• освобождать неиспользуемую память и

• не допускать «утечки» динамически выделяемой памяти.

• POSIX предоставляет для удобства функцию, a GLIBC предоставляет функции и для чтения строк произвольной длины. Функции интерфейса низкоуровневых системных вызовов и предоставляют непосредственный, но примитивный доступ к выделению и освобождению памяти. Если вы не создаете свой собственный распределитель памяти, следует избегать их. Существует функция для выделения памяти в стеке, но ее использование не рекомендуется. Подобно умению распознавать ядовитый плющ, про нее нужно знать лишь для того, чтобы избегать ее.

 

Упражнения

 

1. Начав со структуры –

 

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

2. Сохраняет ли ваша функция завершающий символ конца строки? Объясните, почему.

3. Как ваша функция обрабатывает строки, оканчивающиеся CR‑LF?

4. Как вы инициализируете структуру? В отдельной процедуре? С помощью документированных условий для определенных значений в структуре?

5. Как вы обозначаете конец файла? Как вы указываете, что возникла ошибка ввода/вывода? Должна ли ваша функция сообщать об ошибках? Объясните, почему.

6. Напишите программу, которая использует вашу функцию для ее тестирования, а также другую программу, создающую входные данные для первой программы. Протестируйте функцию.

7. Перепишите вашу функцию с использованием и протестируйте ее. Является ли новый код более сложным или менее сложным? Какова его производительность по сравнению с версией?

8. Изучите страницу справки V7 для end (3) (в дистрибутиве V7). Пролила ли она свет на то, как может работать ''?

9. Усовершенствуйте так, чтобы она печатала расположение аргументов и переменных окружения. В какой области адресного пространства они находятся?

 

 

Глава 4

Файлы и файловый ввод/вывод

 

Данная глава описывает базовые файловые операции: открытие и создание файлов, чтение и запись в них, перемещение в них и их закрытие. По ходу дела она представляет стандартные механизмы для обнаружения ошибок и сообщений о них. Глава заканчивается описанием того, как установить длину файла и принудительно сбросить данные файла и вспомогательные данные на диск.

 


Поделиться с друзьями:

Общие условия выбора системы дренажа: Система дренажа выбирается в зависимости от характера защищаемого...

Индивидуальные и групповые автопоилки: для животных. Схемы и конструкции...

История создания датчика движения: Первый прибор для обнаружения движения был изобретен немецким физиком Генрихом Герцем...

Адаптации растений и животных к жизни в горах: Большое значение для жизни организмов в горах имеют степень расчленения, крутизна и экспозиционные различия склонов...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.019 с.