Читаем Основы программирования в Linux полностью

Первая функция printf пытается вывести строку, полученную от указателя null; далее sprintf пытается записать по указателю null. В данном случае Linux (под видом библиотеки GNU С) простила чтение и просто предоставила "магическую" строку, содержащую символы (null)\0. Система не столь терпима в случае записи и просто завершила программу. Такое поведение порой полезно при выявлении программных ошибок.

Если вы повторите попытку, но не будете использовать библиотеку GNU С, вы обнаружите, что безадресное чтение не разрешено. Далее приведена программа memory5b.c:

#include

#include

#include

int main {

 char z = *(const char *)0;

 printf("I read from location zero\n");

 exit(EXIT_SUCCESS);

}

Вы получите следующий результат:

$ ./memory5b

Segmentation fault

В этот раз вы пытаетесь прочесть непосредственно из нулевого адреса. Между вами и ядром теперь нет GNU-библиотеки libc, и программа прекращает выполнение. Имейте в виду, что некоторые системы UNIX разрешают читать из нулевого адреса, ОС Linux этого не допускает.

<p>Освобождение памяти</p>

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

Программы, применяющие память на динамической основе, должны всегда возвращать неиспользованную память диспетчеру распределения памяти malloc с помощью вызова free. Это позволяет выделить блоки, нуждающиеся в повторном объединении, и дает возможность библиотеке malloc следить за памятью, вместо того, чтобы заставлять приложение управлять ею. Если выполняющаяся программа (процесс) использует, а затем освобождает память, эта освободившаяся память остается выделенной процессу. За кадром система Linux управляет блоками памяти, которые программист использует как набор физических "страниц" в памяти, размером 4 Кбайт каждая. Но если страница памяти в данный момент не используется, диспетчер управления памятью ОС Linux сможет переместить ее из оперативной памяти в область свопинга (это называется обменом страниц), где она слабо влияет на потребление ресурсов. Если программа пытается обратиться к данным на странице, которая была перенесена в область свопинга, Linux на очень короткое время приостанавливает программу, возвращает страницу обратно из области свопинга в физическую память и затем разрешает программе продолжить выполнение так, будто данные все время находились в оперативной памяти.

#include

void free(void *ptr_to_memory);

Вызов free следует выполнять только с указателем на память, выделенную с помощью вызова malloc, calloc или realloc. Очень скоро вы встретитесь с функциями calloc и realloc. А сейчас выполните упражнение 7.6.

Упражнение 7.6. Освобождение памяти

Эта программа называется memory6.c.

#include

#include

#define ONE_K (1024)

int main {

 char *some_memory;

 int exit code = EXIT_FAILURE;

 some_memory = (char*)malloc(ONE_K);

 if (some_memory != NULL) {

  free(some_memory);

  printf("Memory allocated and freed again\n");

  exit_code = EXIT_SUCCESS;

 }

 exit(exit_code);

}

Вывод программы следующий:

$ ./memory6

Memory allocated and freed again

Как это работает

Эта программа просто показывает, как вызвать функцию free с указателем, направленным на предварительно выделенную область памяти.

Примечание

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

<p>Другие функции распределения памяти</p>

Две другие функции распределения или выделения памяти calloc и realloc применяются не так часто, как malloc и free.

Далее приведены их прототипы:

#include

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже