Um ponteiro apontando para 0x0000 é o mesmo que um ponteiro definido como NULL? Se o valor NULL for definido no idioma C, para que local ele traduz fisicamente? É o mesmo que 0x0000. Onde posso encontrar mais detalhes sobre esses conceitos?
Um ponteiro apontando para 0x0000 é o mesmo que um ponteiro definido como NULL? Se o valor NULL for definido no idioma C, para que local ele traduz fisicamente? É o mesmo que 0x0000. Onde posso encontrar mais detalhes sobre esses conceitos?
Respostas:
Um ponto que a maioria das respostas aqui não aborda, pelo menos não explicitamente, é que um ponteiro nulo é um valor que existe durante a execução, e uma constante de ponteiro nulo é uma construção sintática que existe no código-fonte C.
Uma constante de ponteiro nulo , como a resposta de Karlson afirma corretamente, é uma expressão constante inteira com o valor 0 (um exemplo simples 0
é o mais comum) ou uma expressão convertida em void*
(como (void*)0
).
NULL
é uma macro, definida em <stddef.h>
vários cabeçalhos padrão, que se expande para uma constante de ponteiro nulo definida pela implementação . A expansão geralmente é um 0
ou outro ((void*)0)
(os parênteses externos são necessários para satisfazer outras regras de idioma).
Portanto, um literal 0
, quando usado em um contexto que requer uma expressão do tipo ponteiro, sempre avalia como um null pointer
valor de ponteiro exclusivo que não aponta para nenhum objeto. Isso não implica nada na representação de um ponteiro nulo . Ponteiros nulos são comumente representados como todos os bits zero, mas podem ser representados como qualquer coisa. Mas mesmo que um ponteiro nulo é representado como 0xDEADBEEF
, 0
ou (void*)0
ainda é uma constante ponteiro nulo .
Esta resposta à pergunta sobre stackoverflow cobre isso muito bem.
Isso implica, entre outras coisas, que memset()
ou calloc()
, que pode definir uma região da memória para todos os bits-zero, não definirá necessariamente nenhum ponteiro nessa região como ponteiro nulo. É provável que o façam na maioria das implementações, mas a linguagem não garante isso.
Não sei por que essa pergunta não é considerada uma duplicata desta , nem como é atual aqui.
NULL
, ou qualquer constante de ponteiro nulo , a um objeto ponteiro define o valor desse objeto para um ponteiro nulo . No nível da máquina, pode muito bem apontar para algum pedaço de memória válido. A desreferencia de um ponteiro nulo tem um comportamento indefinido; acessar um pedaço de memória no endereço 0x0000000
é um comportamento válido, como é literalmente qualquer outra coisa. Esse endereço difere de qualquer outro endereço por (a) comparar igual a NULL
e (b) comparar desigual com qualquer ponteiro para um objeto C. Um ponteiro nulo é um valor arbitrário de ponteiro usado para indicar que não aponta para nada.
Toda plataforma disponível é livre para definir NULL como quiser.
De acordo com o Padrão C, se você atribuir zero a um ponteiro, ele será convertido em um valor NULL (para essa plataforma). No entanto, se você pegar um ponteiro NULL e convertê-lo em int, não há garantias de que você obterá zero em todas as plataformas existentes. O fato, porém, é que, na maioria das plataformas, será zero.
Informações sobre esse material podem ser encontradas em The C Language Specification . Uma fonte cuja confiabilidade não posso garantir é a seguinte: http://www.winapi.co.kr/pds/doc/ISO-C-FDIS.1999-04.pdf
NULL pointer constant
. Até onde eu sei, não existem compiladores que façam isso.
NULL
macro, que deve ser expandida para 0
C ++ e C 0
ou (void *)0
porque essa é a verdadeira "constante de ponteiro nulo".
É definido na linguagem C porque não há um endereço de máquina invariável ao qual ele se iguala. Se isso acontecesse, não precisaríamos de uma abstração! Embora na maioria das plataformas, o NULL possa eventualmente ser implementado como 0 de um tipo ou de outro, é simplesmente errado supor que isso seja universalmente verdade, se você se importa com a portabilidade.
De acordo com a seção do documento padrão C6.3.2.3
:
Uma expressão constante inteira com o valor 0, ou uma expressão convertida para digitar void *, é chamada de constante de ponteiro nulo.55) Se uma constante de ponteiro nulo é convertida em um tipo de ponteiro, o ponteiro resultante, chamado de ponteiro nulo, é garantido para comparar desigual a um ponteiro para qualquer objeto ou função.
Até agora, eu não vi um compilador que se separou disso.