Что такое "ошибка присваивания нулевого указателя"?

Один из вопросов о собеседовании на C-указателях здесь: что такое ошибка присваивания нулевого указателя?

Я искал время в Интернете и не вижу никаких разумных объяснений. Что это? Пытаетесь написать через нулевой указатель? Что-то архитектурное или экологическое? Что это за ошибка?

Ответ 1

http://www.faqs.org/qa/qa-3786.html

Назначение указателя NULL - это ошибка времени выполнения Это связано с различными причинами: ваша программа пыталась получить доступ к нелегальной ячейке памяти.    Недопустимое местоположение означает, что местоположение находится в адресном пространстве операционных систем или в другом пространстве памяти процессов.   В stdio.h NULL определяется как 0   Поэтому всякий раз, когда ваша программа пытается получить доступ к 0-му местоположению, операционная система убивает вашу программу с ошибкой назначения времени выполнения, поскольку 0-е место находится в адресном пространстве операционных систем, и операционная система не разрешает доступ к ее адресному пространству с помощью пользовательской программы.

Пример кода:

int* ptr = NULL;  
*ptr = 3;

Объяснение:
Почти для каждой системы зарезервирован адрес 0. Система не позволит вам писать в это место. Если вы попытаетесь, вы получите исключение во время выполнения (нарушение прав доступа, ошибка сегментации и т.д.).

Ответ 2

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

Давайте рассмотрим случай компилятора TC, этот компилятор помещает четыре нулевых байта в нижней части сегмента данных и уведомление об авторских правах TC. TC также использует местоположение DS: 0000, в нижней части сегмента данных, как местоположение нулевых указателей. Таким образом, присваивая значение этому нулевому указателю, явным образом изменил бы четыре байта и, вероятно, испортил бы уведомление об авторских правах.

Теперь, при завершении программы, четыре нули и баннер авторских прав проверяются на любые изменения. Если какие-либо изменения найдены, он генерирует ошибку Null Pointer Assignment.

Итак, я думаю, что это не просто нулевой указатель, любой указатель, который становится диким, если пытается получить доступ к некоторым ключевым областям, вас приветствует ошибка Null Pointer Assignment.

Ответ 3

Существует много сценариев, в которых вы можете увидеть проблемы. Но главное в том, что вы не правильно распределили память. Следующий код создаст сообщение об ошибке присвоения указателя Null после запуска программы. Примечание. Он будет правильно компилироваться.

void CopyMessage(char *p)
{
    strcpy(p, "welcome");
}

void main()
{
   char *src;
   CopyMessage(src);
}

Ответ 4

Это ошибка времени выполнения, когда вы пытаетесь указать нелегальное пространство памяти, обычно адрес 0, зарезервированный для ОС.

Ответ 5

2017-10-27: rewrite

Это описание выходит за рамки обычного определения ошибки с нулевым указателем, но тем не менее оно может генерировать нулевой указатель, хотя чаще всего создает другие ошибки или вообще ничего. Он часто не дает никаких указаний о его существовании, кроме как "если или когда" программа не выполняет, как ожидалось. Это дает нетрадиционные примеры и определения потенциальных источников ошибок присваивания нулевых указателей, а не определение обычного понимания, которое скорее является ошибкой в ​​согласии, чем ошибкой в ​​логике программирования.

Этот тип ошибки (undefined или null) намного реже. Но современное программирование, использующее настольные устройства, такие как Arduino, Raspberry PI, AMD или любой другой компьютер на чип-программировании, существует во множестве форм, многие из которых так же просты сегодня, как и прошлые годы, эта проблема все еще существует сегодня и может произойти даже в самых сложных системах. Кроме того, компании, которые строят свою собственную переменную или структуры данных, вероятно, также являются наиболее вероятными людьми, которые сейчас видят это. Цель состоит в том, чтобы показать примеры, которые могут помочь в распознавании.

Чтобы это было ошибкой указателя "null", присваиваемое значение должно быть "0" или "null". Но исторически он был назван "ошибкой нулевого указателя", а не просто простым указателем на нуль; но из-за их возникновения при очистке или обнулении массива, процедура делает так, что перерегулирует или недопустит границы массива. Тем не менее, просто это ошибка, созданная просчетами границ массива, которые могут создавать присвоения нулевого указателя и другие ошибки. Они часто не легко обнаруживаются и не могут генерировать ошибку немедленно или вообще, потому что адрес, указатель которого первоначально указывал на то, когда он определен, был перезаписан и теперь содержит нежелательное значение (плохой адрес). И когда и по какой-то ссылке было почти невозможно найти. Это включено как часть определения типов ошибок, которые порождают нулевые указатели. Если указатель будет перезаписан нулевым или нулевым, и он будет генерировать ошибку, и один останется с проблемой поиска того, что изменило его. Необходимо проявлять особую осторожность, чтобы убедиться, что индексы рассчитаны надлежащим образом с соответствующим рассмотрением с базовым вариантом 0 или 1. Также также правильно вычисляется при перемещении блоков данных. К счастью, многие сложные программные приложения для разработки и языки высокого уровня могут уловить многие из этих проблем до или во время компиляции, когда тип массива переменных явно отображается, или когда программа может быть записана в среде выполнения и контролирует границы массива.

Нулевой указатель, как было определено в более старые времена, представляет собой любую переменную, которая используется как указатель и содержимое адреса адреса указателя, то есть адрес, на который указывает указатель, а не местоположение, на которое он указывает, равен нулю или null, OR был изменен, перезаписан без намерения программиста или знания, которое может быть нулевым, но может быть любым другим значением. Часто только нулевой указатель создает сообщение об ошибке, даже если код может создать ошибку, так как он часто блокирует данные, содержащие нули, которые записываются в неправильные местоположения. Вместо того, чтобы указывать на исходный определенный адрес, где должны находиться данные, он теперь содержит нулевой или неизвестный адрес, перемещающий данные, в недействительную или нежелательную запись места и искажение кода или данных там. Поскольку сбой, вызванный данными, или код может не выполняться немедленно или использоваться, когда он перемещается в существующее неиспользуемое место памяти, когда код или данные действительно вызывают проблему в более позднее время в прогоне, не может быть никакой информации в "реальном" месте ошибки, создает ли он или назначает нулевые указатели или другое повреждение, он изменяет код, и все может стать странным, действительно странным.

Подводя итог, нулевой указатель - это любой нулевой адрес, используемый для указания на ячейку памяти независимо от того, что ее создает. Для этой проблемы и примера может быть назначена ошибка присваивания нулевого указателя или множество других ошибок.

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

Итак, наконец, можно получить ошибку с нулевым указателем, и после изучения указателя он содержит нуль; но не может найти код, который поместил нуль в указатель или назначил его. Это широкое определение ошибки присваивания нулевого указателя и является наихудшим сценарием ошибки нулевого указателя. Когда это происходит в большой программе, это может быть смертью программы, потому что если ошибка существовала ранее и записывалась в неправильную ячейку памяти, и это местоположение еще не было выделено, ошибка остается незамеченной до тех пор, пока программа не будет расширена, и теперь неправильное расположение памяти может существовать внутри нового кода, генерируя случайные ошибки. Например: неправильное значение адреса заставляет данные записываться за пределами определенного пространства переменных, но остается незаметным в течение некоторого времени, потому что он записывается и читается, и все "появляется" ОК! Но программа расширяется, становится больше, новый код существует в том же адресном пространстве, что и память, в которой была оригинальная старая ошибка, которая записывает данные в неправильное адресное пространство, и никто не заметил, будь то один байт или целый блок данных! Но теперь там есть новый код. И он повреждается старым неоткрытым багом, и найти ошибку, которая существовала годом ранее, теперь почти, если не полностью, невозможно найти. Логика администратора обычно диктует, зачем смотреть туда, она работает и отлично работает в прошлом году. Но теперь ничего не работает, крупные части разбиты, выглядят и смотрят, и ничего не вы найдете. Это как будто ошибка не существует, и все же это происходит. Что вызывает это, кто подозревает код, написанный несколько лет назад? Это также вызваны нулевыми указателями и многими другими ошибками.

Возможно, этот ответ неуместен и лучше будет перечисляться в другом месте. Модератор? Возможно, существует проблема, потому что этот "ответ" не считается уместным, потому что существует некоторая озабоченность по поводу использования слова "назначение" в вопросе, что означает намеренно назначенное. Однако концепция уступки не требует знания или согласия. Алгоритм или код могут назначать значения. Нулевые указатели могут быть созданы разными способами, пример здесь, вероятно, является наиболее распространенным из-за обычных ошибок.

Похоже, эта информация имеет "а" место и включена здесь в качестве ответа. Позитивная плодотворная обратная связь или предложения оцениваются, а не простой голос, если кто-то хочет комментировать, возможно, мета-обсуждение в порядке?

Приветствия.