Я изучал C ++, и мне трудно понять ноль. В частности, в руководствах, которые я прочитал, упоминается «проверка на ноль», но я не уверен, что это значит или почему это необходимо.
- Что именно является нулевым?
- Что значит «проверить на ноль»?
- Мне всегда нужно проверять на ноль?
Любые примеры кода будут высоко оценены.
Ответы:
В C и C ++ указатели по своей природе небезопасны, то есть, когда вы разыменовываете указатель, вы несете ответственность за то, чтобы убедиться, что он указывает где-то верным; это часть «ручного управления памятью» (в отличие от схем автоматического управления памятью, реализованных в таких языках, как Java, PHP или .NET, которые не позволяют создавать недопустимые ссылки без значительных усилий).
Распространенное решение, которое ловит много ошибок, состоит в том, чтобы установить все указатели, которые не указывают ни на что как
NULL
(или, в правильном C ++,0
), и проверять это перед доступом к указателю. В частности, обычной практикой является инициализация всех указателей в NULL (если у вас уже нет на что указывать, когда вы их объявляете), и установите их в NULL, когда выdelete
илиfree()
они (если они сразу не выходят из области видимости). Пример (на C, но также и на C ++):Лучшая версия:
Без проверки NULL передача указателя NULL в эту функцию вызовет segfault, и вы ничего не сможете сделать - ОС просто убьет ваш процесс и, возможно, вызовет дамп ядра или откроет диалоговое окно отчета о сбое. С установленной нулевой проверкой вы можете выполнить надлежащую обработку ошибок и корректно восстановиться - исправить проблему самостоятельно, прервать текущую операцию, записать запись в журнал, уведомить пользователя, что угодно.
источник
Другие ответы в значительной степени охватили ваш точный вопрос. Нулевая проверка выполняется, чтобы убедиться, что полученный вами указатель действительно указывает на допустимый экземпляр типа (объекты, примитивы и т. Д.).
Я собираюсь добавить свой собственный совет здесь, хотя. Избегайте нулевых проверок. :) Null проверяет (и другие формы защитного программирования) загромождение кода и фактически делает его более подверженным ошибкам, чем другие методы обработки ошибок.
Моя любимая техника, когда дело доходит до объектных указателей - это использование шаблона Null Object . Это означает, что нужно возвращать (указатель - или, что еще лучше, ссылку на) пустой массив или список вместо нуля, или возвращать пустую строку ("") вместо нуля, или даже строку "0" (или что-то, эквивалентное "ничему" "в контексте), где вы ожидаете, что он будет проанализирован в целое число.
В качестве бонуса, вот кое-что, чего вы, возможно, не знали о нулевом указателе, который (впервые формально) был реализован CAR Hoare для языка Algol W в 1965 году.
источник
Значение нулевого указателя представляет собой четко определенное «нигде»; это недопустимое значение указателя, которое гарантированно сравнивается с любым другим значением указателя. Попытка разыменования нулевого указателя приводит к неопределенному поведению и, как правило, приводит к ошибке во время выполнения, поэтому вы должны убедиться, что указатель не равен NULL, прежде чем пытаться разыменовать его. Ряд библиотечных функций C и C ++ вернет нулевой указатель, указывающий на состояние ошибки. Например, библиотечная функция
malloc
будет возвращать нулевое значение указателя, если она не сможет выделить количество запрошенных байтов, а попытка получить доступ к памяти через этот указатель (обычно) приведет к ошибке времени выполнения:Поэтому мы должны убедиться, что
malloc
вызов выполнен успешно, проверив значение параметраp
против NULL:Теперь, подожди минутку, это будет немного неровно.
Существует значение нулевого указателя и константа нулевого указателя , и они не обязательно совпадают. Указатель нулевой значение является любое значение , лежащие в основе использования архитектуры не представляют «нигде». Это значение может быть 0x00000000, или 0xFFFFFFFF, или 0xDEADBEEF, или что-то совершенно другое. Не думайте , что указатель нулевого значение всегда 0.
Указатель нулевого постоянная , Ото, всегда 0-значное интегральное выражение. Что касается вашего исходного кода , 0 (или любое интегральное выражение, которое оценивается как 0) представляет нулевой указатель. И C, и C ++ определяют макрос NULL как константу нулевого указателя. Когда ваш код скомпилирован, константа нулевого указателя будет заменена соответствующим значением нулевого указателя в сгенерированном машинном коде.
Также имейте в виду, что NULL - это только одно из многих возможных недопустимых значений указателя; если вы объявляете переменную автоматического указателя без явной инициализации, например,
значение, изначально сохраненное в переменной, является неопределенным и может не соответствовать действительному или доступному адресу памяти. К сожалению, нет (портативного) способа узнать, является ли значение указателя, отличное от NULL, допустимым или нет, прежде чем пытаться его использовать. Поэтому, если вы имеете дело с указателями, обычно рекомендуется явно инициализировать их значением NULL, когда вы их объявляете, и устанавливать их в NULL, когда они не указывают ни на что активно.
Обратите внимание, что это больше проблема в C, чем в C ++; идиоматический C ++ не должен все время использовать указатели.
источник
Есть несколько методов, все они делают одно и то же.
проверка нуля (проверьте, что указатель равен нулю), версия A
нулевая проверка, версия B
нулевая проверка, версия C
Из трех я предпочитаю использовать первую проверку, так как она явно сообщает будущим разработчикам, что вы пытались проверить, и дает понять, что вы ожидаете, что foo будет указателем.
источник
Вы не Единственная причина использовать указатель в C ++ состоит в том, что вы явно хотите наличие нулевых указателей; иначе вы можете взять ссылку, которая семантически проще в использовании и гарантирует ненулевое значение.
источник
export
) и все C ++ 03 Библиотечные элементы и TR1 и хороший кусок C ++ 11.Если вы не проверяете значение NULL, особенно, если это указатель на структуру, возможно, вы столкнулись с уязвимостью безопасности - разыменованием NULL-указателя. Обращение по нулевому указателю может привести к некоторым другим серьезным уязвимостям безопасности, таким как переполнение буфера, состояние гонки ... которые могут позволить злоумышленнику получить контроль над вашим компьютером.
Многие поставщики программного обеспечения, такие как Microsoft, Oracle, Adobe, Apple ... выпускают программные исправления для устранения этих уязвимостей. Я думаю, что вы должны проверить значение NULL каждого указателя :)
источник