Многие вызовы созывающего кода C:
if (p)
free(p);
Но почему? Я думал, что C-стандарт говорит, что функция free
ничего не делает с указателем NULL. Итак, почему еще одна явная проверка?
Многие вызовы созывающего кода C:
if (p)
free(p);
Но почему? Я думал, что C-стандарт говорит, что функция free
ничего не делает с указателем NULL. Итак, почему еще одна явная проверка?
Конструкция:
free(NULL);
всегда был ОК в C, обратно к исходному компилятору UNIX, написанному Деннисом Ритчи. Предварительная стандартизация, некоторые бедные компиляторы, возможно, не указали ее правильно, но в наши дни любой компилятор, который не может законно назвать себя компилятором для языка C. Использование его обычно приводит к более четкому, более удобному коду.
Как я понимаю, no-op в NULL не всегда был там.
В плохие старые дни C (назад 1986, по стандарту pre-ANSI cc компилятор) бесплатно (NULL) будет сбрасывать ядро. Поэтому большинство разработчиков тестировали NULL/0 перед звоните бесплатно.
Мир прошел долгий путь, и он что нам не нужно делать тест больше. Но старые привычки умирают трудно;)
http://discuss.joelonsoftware.com/default.asp?design.4.194233.15
Я часто пишу "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);
Я знаю, это не разумная причина, а мой случай:)
Составители, даже если вложения не достаточно умны, чтобы знать, что функция немедленно вернется. Нажатие параметров и т.д. На стек и установка вызова вверх, очевидно, дороже, чем тестирование указателя. Я считаю, что всегда хорошая практика избегать выполнения чего-либо, даже если это ничего не работает. Тестирование нулевого значения является хорошей практикой. Еще лучшая практика заключается в том, чтобы убедиться, что ваш код не достигает этого состояния и, следовательно, полностью исключает необходимость в тестировании.
Если вы полагаетесь на это бесплатное (0), это OKAY, и это нормально для вашего указателя на нуль в этот момент, скажите так в комментарии // may be NULL
Это может быть просто самоочевидный код, говорящий, что я знаю, я также использую p как флаг.
может быть пользовательская реализация free() в мобильной среде. В этом случае свободный (0) может вызвать проблему. (да, плохая реализация)
Есть две разные причины, по которым переменная указателя может быть NULL:
потому что переменная используется для того, что в теории типов называется типом опции, и содержит либо указатель на объект, либо NULL, чтобы ничего не представлять,
потому что он указывает на массив и поэтому может быть NULL, если массив имеет нулевую длину (поскольку malloc(0)
разрешено возвращать NULL, определенный реализацией).
Хотя это только логическое различие (в C нет ни типов опций, ни специальных указателей на массивы, и мы просто используем указатели для всего), всегда должно быть ясно, как используется переменная.
Чтобы стандарт C не требовал free(NULL)
ничего не делать, это необходимо, чтобы тот факт, что успешный вызов malloc(0)
может возвратить NULL
. Это не подразумевается как общее удобство, поэтому для примера fclose()
требуется аргумент, отличный от NULL. Нарушение разрешения на вызов free(NULL)
путем передачи NULL, который не представляет массив нулевой длины, кажется хакерским и неправильным.