Страницы

Поиск по вопросам

понедельник, 8 октября 2018 г.

Может ли `free` отработать с ошибкой

Допустим есть кусок кода:
char *ptr = (char*)malloc(needed_size); if (!ptr) { error_handling(); } else { do_something_without_freeing_ptr(); free(ptr); ptr = 0; }
Может ли вызов free не отработать/отработать неправильно и к каким последствиям это может привести?

Подразумевается, что между вызовом malloc и free выделенная память не освобождается, значение указателя не изменяется.
Не лучше ли, во избежание случайного изменения значения ptr, писать:
char * const ptr = malloc(needed_size);
Это не избавит от возможности написать free(ptr); free(ptr);, но по крайней мере убережет от чего-то типа ptr = NULL;


Ответ

free определена как функция, не возвращающая значений, т.е. возможности вернуть ошибку у неё нет. Если ей передать указатель полученный не от calloc, malloc, realloc, либо вызвать повторно для одного и того же указателя или изменить байты за пределами запрошенного массива, действия зависят от реализации. Обычно это приводит к непредсказуемым ошибкам в программе, возможно в совершенно другом месте. Такие ошибки трудно локализовать.
К примеру, в начале выделенного куска памяти перед тем, на что указывает указатель, обычно находится заголовок — структура с информацией об этом куске и о следующем. Кроме этого, где-то может быть информация о свободных кусках. Если, например, в результате функции gets() будет испорчен заголовок для следующего блока, то проявиться эта ошибка может даже не когда этот блок будет выделен malloc, а когда этот блок будет освобождаться.
Есть библиотеки реализующие набор функций calloc, malloc, realloc, free с дополнительными средствами обнаружения их ошибочного использования.
Написать char * const ptr = malloc(needed_size); можно, но это не гарантирует, что вы не скопируете указатель в другую переменную или примените индекс за пределами [0; needed_size[.

Комментариев нет:

Отправить комментарий