Kniga-Online.club
» » » » Linux программирование в примерах - Роббинс Арнольд

Linux программирование в примерах - Роббинс Арнольд

Читать бесплатно Linux программирование в примерах - Роббинс Арнольд. Жанр: Интернет год 2004. Так же читаем полные версии (весь текст) онлайн без регистрации и SMS на сайте kniga-online.club или прочесть краткое содержание, предисловие (аннотацию), описание и ознакомиться с отзывами (комментариями) о произведении.
Перейти на страницу:

 return copy; /* при ошибке возвращает NULL */

}

С появлением стандарта POSIX 2001 программисты по всему миру могут вздохнуть свободнее: эта функция является теперь частью POSIX в виде расширения XSI:

#include <string.h> /* XSI */

char *strdup(const char *str); /* Копировать str */

Возвращаемое значение равно NULL, если была ошибка, или указатель на динамически выделенную память с копией str. Возвращенное значение должно быть освобождено с помощью free(), когда больше не требуется.

3.2.3. Системные вызовы: brk() и sbrk()

Четыре функции, которые мы рассмотрели (malloc(), calloc(), realloc() и free()) являются стандартными, переносимыми функциями для управления динамической памятью.

На Unix-системах стандартные функции реализованы поверх двух дополнительных, очень примитивных процедур, которые непосредственно изменяют размер адресного пространства процесса. Мы представляем их здесь, чтобы помочь вам понять, как работают GNU/Linux и Unix (снова «под капотом»); крайне маловероятно, что вам когда-нибудь понадобится использовать эти функции в обычных программах. Они определены следующим образом:

#include <unistd.h> /* Обычный */

#include <malloc.h> /* Необходим для систем GLIBC 2 */

int brk(void *end_data_segment);

void *sbrk(ptrdiff_t increment);

Системный вызов brk() действительно изменяет адресное пространство процесса. Адрес является указателем, представляющим окончание сегмента данных (на самом деле, области кучи, как было показано ранее на рис. 3.1). Ее аргумент является абсолютным логическим адресом, представляющим новое окончание адресного пространства. В случае успеха функция возвращает 0, а в случае неуспеха (-1).

Функцию sbrk() использовать проще; ее аргумент является числом байтов, на которое нужно увеличить адресное пространство. Вызвав ее с приращением 0, можно определить, где в настоящее время заканчивается адресное пространство. Таким образом, чтобы увеличить адресное пространство на 32 байта, используется код следующего вида:

char *p = (char*)sbrk(0); /* получить текущий конец адресного

                             пространства */

if (brk(p + 32) < 0) {

 /* обработать ошибку */

}

/* в противном случае, изменение сработало */

Практически, вам не нужно непосредственно использовать brk(). Вместо этого используется исключительно sbrk() для увеличения (или даже сокращения) адресного пространства. (Вскоре мы покажем, как это делать, в разделе 3.2.5. «Исследование адресного пространства».)

Еще более практично вообще никогда не использовать эти процедуры. Программа, которая их использует, не может затем использовать также и malloc(), и это создает большую проблему, поскольку многие элементы стандартной библиотеки полагаются на использование malloc(). Поэтому использование brk() или sbrk() может приводить к трудно обнаруживаемым крушениям программы.

Но знать о низкоуровневых механизмах стоит, и конечно же, набор функций malloc() реализован с помощью sbrk() и brk().

3.2.4. Вызовы ленивых программистов: alloca()

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

- Робот -

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

/* Заголовок в GNU/Linux, возможно, не на всех Unix-системах */

#include <alloca.h> /* Обычный */

void *alloca(size_t size);

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

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

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

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

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

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

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

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

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

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

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

Перейти на страницу:

Роббинс Арнольд читать все книги автора по порядку

Роббинс Арнольд - все книги автора в одном месте читать по порядку полные версии на сайте онлайн библиотеки kniga-online.club.


Linux программирование в примерах отзывы

Отзывы читателей о книге Linux программирование в примерах, автор: Роббинс Арнольд. Читайте комментарии и мнения людей о произведении.


Уважаемые читатели и просто посетители нашей библиотеки! Просим Вас придерживаться определенных правил при комментировании литературных произведений.

  • 1. Просьба отказаться от дискриминационных высказываний. Мы защищаем право наших читателей свободно выражать свою точку зрения. Вместе с тем мы не терпим агрессии. На сайте запрещено оставлять комментарий, который содержит унизительные высказывания или призывы к насилию по отношению к отдельным лицам или группам людей на основании их расы, этнического происхождения, вероисповедания, недееспособности, пола, возраста, статуса ветерана, касты или сексуальной ориентации.
  • 2. Просьба отказаться от оскорблений, угроз и запугиваний.
  • 3. Просьба отказаться от нецензурной лексики.
  • 4. Просьба вести себя максимально корректно как по отношению к авторам, так и по отношению к другим читателям и их комментариям.

Надеемся на Ваше понимание и благоразумие. С уважением, администратор kniga-online.


Прокомментировать
Подтвердите что вы не робот:*
Подтвердите что вы не робот:*