Beim Programmieren geht es manchmal kaputt. Sie haben einen Fehler gemacht und Ihr Programm versucht, von einer falschen Adresse zu lesen.
Eine Sache, die mir besonders auffällt, ist, dass diese Ausnahmen häufig wie folgt lauten:
Access violation at address 012D37BC in module 'myprog.exe'. Read of address 0000000C.
Jetzt sehe ich viele Fehlerprotokolle und was mir auffällt, ist das: 0000000C. Ist das eine "besondere" Adresse? Ich sehe andere Zugriffsverletzungen mit schlechten Lesezugriffen, aber die Adressen scheinen zufällig zu sein, aber diese kommen immer wieder in ganz anderen Situationen zurück.
windows
error-handling
error-messages
Pieter B
quelle
quelle
0000000C
ist Art und Weise als häufiger00000008
, aber keine der Antworten auf Adresse erscheinen , dass überhaupt: /System.Runtime.CompilerServices.RuntimeHelpers.OffsetToStringData
ist12=0x0C
ein Grund , warum dieser Offset häufiger ist.Antworten:
00000000
ist eine spezielle Adresse (der Nullzeiger).0000000C
ist genau das, was Sie erhalten, wenn Sie dem Nullzeiger einen Versatz von 12 hinzufügen, höchstwahrscheinlich, weil jemand versucht hat, dasz
Element einer Struktur wie der folgenden durch einen Zeiger zu erhalten, der tatsächlich null war.quelle
In Windows ist es illegal , die dereferenzieren gesamte erste und die letzte Seite , mit anderen Worten die erste oder letzte 64 KiB des Prozesses Speicher (die Bereiche
0x00000000
auf0x0000ffff
und0xffff0000
zu0xffffffff
in einer 32-Bit - Anwendung).Dies dient zum Auffangen des undefinierten Verhaltens, einen Nullzeiger oder Index in ein Null-Array zu dereferenzieren. Die Seitengröße beträgt 64 KB, sodass Windows nur verhindern muss, dass der ersten oder letzten Seite ein gültiger Bereich zugewiesen wird.
Dies schützt nicht vor nicht initialisierten Zeigern, die irgendeinen Wert haben könnten (einschließlich gültiger Adressen).
quelle
Warum
0x0C
scheint häufiger als0x08
(ist es wirklich? Ich weiß nicht; und in welchen Arten von Anwendungen?), Könnte dies mit Tabellenzeigern für virtuelle Methoden zu tun haben. Das ist wirklich eher ein Kommentar (wilde Massenraten :), aber es ist etwas größer, also geht es weiter ... Wenn Sie eine Klasse mit virtuellen Methoden haben, werden ihre eigenen Felder um verschoben0x04
. Beispielsweise könnte eine Klasse, die von einer anderen virtuellen Klasse erbt, ein Speicherlayout wie das folgende haben:Ist das ein häufiges Szenario oder sogar nahe? Ich bin mir nicht sicher. Beachten Sie jedoch, dass dies in einer 64-Bit-Anwendung noch interessanter in Richtung des
0x0C
Werts verschoben werden kann:Es gibt also tatsächlich viele Fälle, in denen sich Anwendungen in Nullzeiger-Offsets möglicherweise erheblich überschneiden. Dies ist möglicherweise das erste Feld in einer untergeordneten Klasse oder der Tabellenzeiger für die virtuelle Methode, der benötigt wird, wenn Sie eine virtuelle Methode für eine Instanz aufrufen. Wenn Sie also eine virtuelle Methode für einen
null
Zeiger aufrufen , wird die Zugriffsverletzung für die betreffende Methode angezeigt VMT-Offset. Die Prävalenz dieses bestimmten Werts hat dann möglicherweise etwas mit einer allgemeinen API zu tun, die eine Klasse mit einem ähnlichen Vererbungsmuster bereitstellt, oder eher mit einer bestimmten Schnittstelle (für einige Anwendungsklassen wie DirectX-Spiele durchaus möglich). Es könnte möglich sein, eine einfache häufige Ursache wie diese aufzuspüren, aber ich neige dazu, Anwendungen, die keine Dereferenzierung durchführen, schnell loszuwerden, also ...quelle