Подтвердить что ты не робот

Проверка NULL перед вызовом бесплатного

Многие вызовы созывающего кода C:

if (p)
  free(p);

Но почему? Я думал, что C-стандарт говорит, что функция free ничего не делает с указателем NULL. Итак, почему еще одна явная проверка?

4b9b3361

Ответ 1

Конструкция:

free(NULL);

всегда был ОК в C, обратно к исходному компилятору UNIX, написанному Деннисом Ритчи. Предварительная стандартизация, некоторые бедные компиляторы, возможно, не указали ее правильно, но в наши дни любой компилятор, который не может законно назвать себя компилятором для языка C. Использование его обычно приводит к более четкому, более удобному коду.

Ответ 2

Как я понимаю, no-op в NULL не всегда был там.

В плохие старые дни C (назад 1986, по стандарту pre-ANSI cc компилятор) бесплатно (NULL) будет сбрасывать ядро. Поэтому большинство разработчиков тестировали NULL/0 перед звоните бесплатно.

Мир прошел долгий путь, и он что нам не нужно делать тест больше. Но старые привычки умирают трудно;)

http://discuss.joelonsoftware.com/default.asp?design.4.194233.15

Ответ 3

Я часто пишу "if (p) free(p)", даже если я знаю, что это не нужно.

Я частично виню себя, потому что я узнал, что в старые времена, когда free(NULL) будет segfault, и я все еще чувствую себя некомфортно, не делая этого.

Но я также обвиняю стандарт C в том, что он не является последовательным. Был бы, например, fclose (NULL) быть хорошо определенным, у меня не было бы проблем в письменной форме:

free(p);
fclose(f);

Это то, что происходит очень часто при очистке вещей. К сожалению, мне кажется странным писать

free(p);
if (f) fclose(f);

и я заканчиваю тем, что

if (p) free(p);
if (f) fclose(f);

Я знаю, это не разумная причина, а мой случай:)

Ответ 4

Составители, даже если вложения не достаточно умны, чтобы знать, что функция немедленно вернется. Нажатие параметров и т.д. На стек и установка вызова вверх, очевидно, дороже, чем тестирование указателя. Я считаю, что всегда хорошая практика избегать выполнения чего-либо, даже если это ничего не работает. Тестирование нулевого значения является хорошей практикой. Еще лучшая практика заключается в том, чтобы убедиться, что ваш код не достигает этого состояния и, следовательно, полностью исключает необходимость в тестировании.

Ответ 5

Если вы полагаетесь на это бесплатное (0), это OKAY, и это нормально для вашего указателя на нуль в этот момент, скажите так в комментарии // may be NULL

Это может быть просто самоочевидный код, говорящий, что я знаю, я также использую p как флаг.

Ответ 6

может быть пользовательская реализация free() в мобильной среде. В этом случае свободный (0) может вызвать проблему. (да, плохая реализация)

Ответ 7

Есть две разные причины, по которым переменная указателя может быть NULL:

  • потому что переменная используется для того, что в теории типов называется типом опции, и содержит либо указатель на объект, либо NULL, чтобы ничего не представлять,

  • потому что он указывает на массив и поэтому может быть NULL, если массив имеет нулевую длину (поскольку malloc(0) разрешено возвращать NULL, определенный реализацией).

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

Чтобы стандарт C не требовал free(NULL) ничего не делать, это необходимо, чтобы тот факт, что успешный вызов malloc(0) может возвратить NULL. Это не подразумевается как общее удобство, поэтому для примера fclose() требуется аргумент, отличный от NULL. Нарушение разрешения на вызов free(NULL) путем передачи NULL, который не представляет массив нулевой длины, кажется хакерским и неправильным.