Podczas programowania czasami coś się psuje. Popełniłeś błąd i twój program próbuje odczytać z niewłaściwego adresu.
Jedna rzecz, która wyróżnia mnie, że często te wyjątki to:
Access violation at address 012D37BC in module 'myprog.exe'. Read of address 0000000C.
Teraz widzę wiele dzienników błędów, a wyróżnia mnie: 0000000C. Czy to adres „specjalny”? Widzę inne naruszenia praw dostępu ze złymi odczytami, ale adresy wydają się losowe, ale ten ciągle powraca w zupełnie innych sytuacjach.
windows
error-handling
error-messages
Pieter B.
źródło
źródło
0000000C
jest sposób bardziej powszechne niż00000008
, ale żadna z odpowiedzi wydaje się, że adres w ogóle: /System.Runtime.CompilerServices.RuntimeHelpers.OffsetToStringData
to12=0x0C
jest powód, dlaczego to przesunięcie jest bardziej powszechne.Odpowiedzi:
00000000
to specjalny adres (wskaźnik zerowy).0000000C
jest dokładnie tym, co dostajesz, gdy dodasz przesunięcie 12 do wskaźnika zerowego, najprawdopodobniej dlatego, że ktoś próbował uzyskaćz
element struktury taki jak ten poniżej za pomocą wskaźnika, który w rzeczywistości był zerowy.źródło
W systemie Windows jest nielegalne dereference z całą pierwsza i ostatnia strona , innymi słowy pierwsza lub ostatnia 64 KiB pamięci procesu (zakresy
0x00000000
do0x0000ffff
i0xffff0000
do0xffffffff
w aplikacji 32-bitowych).Ma to na celu uwięzienie niezdefiniowanego zachowania dereferencji wskaźnika zerowego lub indeksu w tablicy zerowej. Rozmiar strony to 64 KiB, więc system Windows musi po prostu uniemożliwić przypisanie pierwszej lub ostatniej stronie prawidłowego zakresu.
Nie ochroni to przed niezainicjowanymi wskaźnikami, które mogą mieć dowolną wartość (w tym prawidłowe adresy).
źródło
Co do tego, dlaczego
0x0C
wydaje się bardziej powszechne niż0x08
(czy to naprawdę? Nie wiem; i w jakich aplikacjach?), Może to mieć związek z wskaźnikami wirtualnej tablicy metod. To jest naprawdę bardziej komentarz (zgadywanie dzikiej masy :), ale jest nieco większy, więc proszę ... Jeśli masz klasę z metodami wirtualnymi, jej pola zostaną przesunięte0x04
. Na przykład klasa dziedzicząca z innej klasy wirtualnej może mieć układ pamięci taki jak ten:Czy jest to częsty scenariusz, czy nawet bliski? Nie jestem pewny. Należy jednak pamiętać, że w 64-bitowej aplikacji może to być jeszcze bardziej interesujące przesunięcie w kierunku
0x0C
wartości:Tak więc w rzeczywistości istnieje wiele przypadków, w których aplikacje mogą znacznie nakładać się na przesunięcia wskaźnika zerowego. Może to być pierwsze pole w klasie podrzędnej lub wskaźnik wirtualnej tablicy metod - potrzebny za każdym razem, gdy wywołasz dowolną metodę wirtualną w instancji, więc jeśli wywołujesz metodę wirtualną na
null
wskaźniku, otrzymasz naruszenie dostępu do jej Przesunięcie VMT. Występowanie tej konkretnej wartości może mieć coś wspólnego z niektórymi typowymi interfejsami API, które zapewniają klasę o podobnym wzorcu dziedziczenia lub, co bardziej prawdopodobne, określony interfejs (całkiem możliwe dla niektórych klas aplikacji, takich jak gry DirectX). Możliwe, że możliwe jest wyśledzenie prostej prostej przyczyny takiej jak ta, ale zwykle pozbywam się aplikacji, które powodują zerowe dereferencje dość szybko, więc ...źródło