Na programação, às vezes as coisas quebram. Você cometeu um erro e seu programa tenta ler de um endereço errado.
Uma coisa que se destaca para mim é que muitas vezes essas exceções são como:
Access violation at address 012D37BC in module 'myprog.exe'. Read of address 0000000C.
Agora vejo muitos logs de erros e o que mais me destaca é o: 0000000C. Este é um endereço "especial"? Vejo outras violações de acesso com leituras ruins, mas os endereços parecem aleatórios, mas esse continua voltando em situações totalmente diferentes.
windows
error-handling
error-messages
Pieter B
fonte
fonte
0000000C
é muito mais comum do que isso00000008
, mas nenhuma das respostas parece abordar isso: /System.Runtime.CompilerServices.RuntimeHelpers.OffsetToStringData
seja12=0x0C
por isso que esse deslocamento seja mais comum.Respostas:
00000000
é um endereço especial (o ponteiro nulo).0000000C
é exatamente o que você obtém ao adicionar um deslocamento de 12 ao ponteiro nulo, provavelmente porque alguém tentou obter oz
membro de uma estrutura como a abaixo através de um ponteiro que era realmente nulo.fonte
No Windows, é ilegal desreferenciar toda a primeira e a última página , ou seja, o primeiro ou o último 64 KiB da memória do processo (os intervalos
0x00000000
de0x0000ffff
e0xffff0000
para0xffffffff
um aplicativo de 32 bits).Isso serve para interceptar o comportamento indefinido de desreferenciar um ponteiro ou índice nulo em uma matriz nula. E o tamanho da página é de 64 KiB; portanto, o Windows precisa impedir que a primeira ou a última página recebam um intervalo válido.
Isso não protegerá contra ponteiros não inicializados que possam ter algum valor (incluindo endereços válidos).
fonte
Quanto ao porquê
0x0C
parece mais comum do que0x08
(é realmente? Eu não sei; e em que tipos de aplicativos?), Isso pode ter a ver com ponteiros de tabela de método virtual. Isso é realmente mais um comentário (adivinhação em massa :), mas é um pouco maior, então aqui vai ... Se você tem uma classe com métodos virtuais, seus próprios campos serão alterados0x04
. Por exemplo, uma classe que herda de outra classe virtual pode ter um layout de memória como este:Esse é um cenário comum, ou até próximo? Não tenho certeza. No entanto, observe que em um aplicativo de 64 bits, isso pode ser ainda mais interessante para o
0x0C
valor:Portanto, existem muitos casos em que os aplicativos podem ter sobreposição significativa nas compensações de ponteiro nulo. Pode ser o primeiro campo de uma classe filho ou seu ponteiro de tabela de método virtual - necessário sempre que você chama qualquer método virtual em uma instância; portanto, se você estiver chamando um método virtual em um
null
ponteiro, terá violação de acesso em seu Deslocamento da VMT. A prevalência desse valor específico pode ter algo a ver com alguma API comum que fornece uma classe que possui um padrão de herança semelhante ou, mais provavelmente, uma interface específica (possível para algumas classes de aplicativos, como jogos do DirectX). Pode ser possível rastrear uma causa comum simples como essa, mas eu costumo me livrar de aplicativos que fazem a desreferenciação nula muito rapidamente, então ...fonte