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



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

>struct coord { /* 3D координаты */

> int x, y, z;

>} *coordinates;

>unsigned int count; /* сколько нам нужно */

>size_t amount; /* общий размер памяти */

>/* ... как-нибудь определить нужное число... */

>amount = count * sizeof(struct coord); /* сколько байт выделить */

>coordinates = (struct coord*)malloc(amount); /* выделить память */

>if (coordinates == NULL) {

> /* сообщить об ошибке, восстановить или прервать */

>}

>/* ... использовать координаты... */

Представленные здесь шаги являются стереотипными. Порядок следующий:

1. Объявить указатель соответствующего типа для выделенной памяти.

2. Вычислить размер выделяемой памяти в байтах. Для этого нужно умножить число нужных объектов на размер каждого из них. Последний получается с помощью оператора С >sizeof, который для этой цели и существует (наряду с другими). Таким образом, хотя размер определенной структуры среди различных компиляторов и архитектур может различаться, >sizeof всегда возвращает верное значение, а исходный код остается правильным и переносимым.

При выделении массивов для строк символов или других данных типа >char нет необходимости умножения на >sizeof(char), поскольку последнее по определению всегда равно 1. Но в любом случае это не повредит.

3. Выделить память с помощью >malloc(), присвоив возвращаемое функцией значение переменной указателя. Хорошей практикой является приведение возвращаемого >malloc() значения к типу переменной, которой это значение присваивается. В С этого не требуется (хотя компилятор может выдать предупреждение). Мы настоятельно рекомендуем всегда приводить возвращаемое значение.

Обратите внимание, что на C++ присвоение знамения указателя одного типа указателю другого типа требует приведения типов, какой бы ни был контекст. Для управления динамической памятью программы C++ должны использовать >new и >delete, а не >malloc() и >free(), чтобы избежать проблем с типами.

4. Проверить возвращенное значение. Никогда не предполагайте, что выделение памяти было успешным. Если выделение памяти завершилось неудачей, >malloc()