Linux программирование в примерах | страница 54



возвращает >NULL. Если вы используете значение без проверки, ваша программа может быть немедленно завершена из-за нарушения сегментации (segmentation violation), которое является попыткой использования памяти за пределами своего адресного пространства.

Если вы проверите возвращенное значение, вы можете по крайней мере выдать диагностическое сообщение и корректно завершить программу. Или можете попытаться использовать какой-нибудь другой способ восстановления.

Выделив блок памяти и установив в >coordinates указатель на него, мы можем затем интерпретировать >coordinates как массив, хотя он в действительности указатель:

>int cur_x, cur_y, cur_z;

>size_t an_index;

>an_index = something;

>cur_x = coordinates[an_index].x;

>cur_y = coordinates[an_index].y;

>cur_z = coordinates[an_index].z;

Компилятор создает корректный код для индексирования через указатель при получении доступа к членам структуры >coordinates[an_index].

ЗАМЕЧАНИЕ. Блок памяти, возвращенный >malloc(), не инициализирован. Он может содержать любой случайный мусор. Необходимо сразу же инициализировать память нужными значениями или хотя бы нулями. В последнем случае используйте функцию >memset() (которая обсуждается в разделе 12.2 «Низкоуровневая память, функции >memXXX()):

>memset(coordinates, '\0', amount);

Другой возможностью является использование >calloc(), которая вскоре будет описана.

Джефф Колье (Geoff Collyer) рекомендует следующую методику для выделения памяти:

>some_type *pointer;

>pointer = malloc(count * sizeof(*pointer));

Этот подход гарантирует, что >malloc() выделит правильное количество памяти без необходимости смотреть объявление pointer. Если тип >pointer впоследствии изменится, оператор >sizeof автоматически гарантирует, что выделяемое число байтов остается правильным. (Методика Джеффа опускает приведение типов, которое мы только что обсуждали. Наличие там приведения типов также гарантирует диагностику, если тип >pointer изменится, а вызов >malloc() не будет обновлен.)

3.2.1.3. Освобождение памяти: >free()

Когда вы завершили использование памяти, «верните ее обратно», используя функцию >free(). Единственный аргумент является указателем, предварительно полученным с использованием другой функции выделения. Можно (хотя это бесполезно) передать функции >free() пустой указатель:

>free(coordinates);

>coordinates = NULL; /* не требуется, но хорошая мысль */

После вызова f>ree(coordinates) доступ к памяти, на которую указывает >coordinates