При программировании иногда что-то ломается. Вы ошиблись, и ваша программа пытается прочитать не с того адреса.
Одна вещь, которая выделяет меня, что часто эти исключения похожи на:
Access violation at address 012D37BC in module 'myprog.exe'. Read of address 0000000C.
Теперь я вижу много журналов ошибок, и что мне выделяется: 0000000C. Это «специальный» адрес? Я вижу другие нарушения доступа с плохим чтением, но адреса кажутся случайными, но этот постоянно возвращается в совершенно разных ситуациях.
windows
error-handling
error-messages
Питер Б
источник
источник
0000000C
есть способ более распространен , чем00000008
, но ни один из ответов не кажется, что адрес на всех: /System.Runtime.CompilerServices.RuntimeHelpers.OffsetToStringData
это12=0x0C
является причиной , почему это смещение является более распространенным.Ответы:
00000000
это специальный адрес (нулевой указатель).0000000C
это именно то, что вы получаете, когда добавляете смещение 12 к нулевому указателю, скорее всего потому, что кто-то пытался получитьz
член структуры, такой как ниже, через указатель, который был фактически нулевым.источник
В Windows запрещено разыменовывать всю первую и последнюю страницы , другими словами, первые или последние 64 КБ памяти процесса (диапазоны
0x00000000
до0x0000ffff
и0xffff0000
до0xffffffff
в 32-битном приложении).Это необходимо для ловушки неопределенного поведения разыменования нулевого указателя или индекса в нулевой массив. И размер страницы составляет 64 КБ, поэтому Windows просто нужно предотвратить допустимый диапазон для первой или последней страницы.
Это не защитит от неинициализированных указателей, которые могут иметь любое значение (включая действительные адреса).
источник
Что касается того, почему
0x0C
кажется более распространенным, чем0x08
(действительно ли это? Я не знаю; и в каких типах приложений?) Это может быть связано с указателями таблиц виртуальных методов. Это на самом деле больше комментарий (угадывание дикой массы :), но он несколько больше, так что здесь ... Если у вас есть класс с виртуальными методами, его собственные поля будут сдвинуты0x04
. Например, класс, который наследуется от другого виртуального класса, может иметь такую структуру памяти:Это общий сценарий или даже близкий? Я не уверен. Однако обратите внимание, что в 64-битном приложении это может быть еще более интересно смещено в сторону
0x0C
значения:Так что на самом деле во многих случаях приложения могут значительно перекрывать смещения нулевого указателя. Это может быть первое поле в дочернем классе или указатель его таблицы виртуальных методов - необходимо всякий раз, когда вы вызываете любой виртуальный метод в экземпляре, поэтому, если вы вызываете виртуальный метод для
null
указателя, вы получите нарушение доступа к его Смещение ВМТ. Распространенность этого конкретного значения может тогда иметь какое-то отношение к какому-то общему API, предоставляющему класс с аналогичным шаблоном наследования или, скорее, конкретный интерфейс (что вполне возможно для некоторых классов приложений, таких как игры DirectX). Можно было бы отследить какую-то простую общую причину, как это, но я склонен избавляться от приложений, которые довольно быстро разыменовывают нулевую разыменование, так что ...источник