¿Un puntero que apunta a 0x0000 es lo mismo que un puntero establecido en NULL? Si el valor NULL se define en el lenguaje C, ¿a qué ubicación se traduce físicamente? ¿Es lo mismo que 0x0000? ¿Dónde puedo encontrar más detalles sobre estos conceptos?
12
Respuestas:
Un punto que la mayoría de las respuestas aquí no están abordando, al menos no explícitamente, es que un puntero nulo es un valor que existe durante la ejecución, y una constante de puntero nulo es una construcción sintáctica que existe en el código fuente C.
Una constante de puntero nulo , como dice correctamente la respuesta de Karlson, es una expresión constante entera con el valor 0 (un simple
0
es el ejemplo más común) o una expresión de ese tipo convertida avoid*
(como(void*)0
).NULL
es una macro, definida en<stddef.h>
y varios otros encabezados estándar, que se expande a una constante de puntero nulo definida por la implementación . La expansión generalmente es0
o((void*)0)
(los paréntesis externos son necesarios para satisfacer otras reglas del lenguaje).Entonces, un literal
0
, cuando se usa en un contexto que requiere una expresión de tipo puntero, siempre se evalúa como unnull pointer
valor de puntero único que no apunta a ningún objeto. Eso no implica nada sobre la representación de un puntero nulo . Los punteros nulos se representan comúnmente como todos los bits cero, pero se pueden representar como cualquier cosa. Pero incluso si un puntero nulo se representa como0xDEADBEEF
,0
o(void*)0
sigue siendo una constante de puntero nulo .Esta respuesta a la pregunta sobre stackoverflow cubre esto bien.
Esto implica, entre otras cosas, que
memset()
ocalloc()
, que puede establecer una región de memoria en todos los bits cero, no establecerá necesariamente ningún puntero en esa región en punteros nulos. Es probable que lo hagan en la mayoría de las implementaciones, pero el lenguaje no lo garantiza.No sé por qué esta pregunta no se considera un duplicado de esta , o cómo es de actualidad aquí.
fuente
NULL
, o cualquier constante de puntero nulo , a un objeto puntero establece el valor de ese objeto en un puntero nulo . En el nivel de la máquina, puede apuntar a algún fragmento de memoria válido. Anular la referencia a un puntero nulo tiene un comportamiento indefinido; Acceder a un trozo de memoria en la dirección0x0000000
es un comportamiento válido, como lo es literalmente cualquier otra cosa. Esa dirección difiere de cualquier otra dirección por (a) comparar igual aNULL
, y (b) comparar desigual a cualquier puntero a un objeto C. Un puntero nulo es un valor de puntero arbitrario utilizado para indicar que no apunta a nada.Cada plataforma es libre de definir NULL como le plazca.
Según el Estándar C, si asigna cero a un puntero, se convertirá en un valor NULL (para esa plataforma). Sin embargo, si toma un puntero NULL y lo convierte en int, no hay garantías de que obtendrá cero en cada plataforma por ahí. Sin embargo, el hecho es que en la mayoría de las plataformas será cero.
Puede encontrar información sobre esas cosas en The C Language Specification . Una fuente, cuya fiabilidad no puedo garantizar, es esta: http://www.winapi.co.kr/pds/doc/ISO-C-FDIS.1999-04.pdf
fuente
NULL pointer constant
. Hasta donde sé, no hay compiladores que lo hagan.NULL
macro, que debe expandirse0
en C ++ y en C0
o(void *)0
, porque esa es la verdadera "constante de puntero nulo".Se define en el lenguaje C porque no hay una sola dirección de máquina invariable a la que equivale. Si lo hiciera, ¡no necesitaríamos una abstracción de él! Aunque en la mayoría de las plataformas, NULL podría implementarse eventualmente como 0 de algún tipo u otro, simplemente es incorrecto suponer que esto es universal, si le importa la portabilidad.
fuente
De acuerdo con la sección del documento estándar C
6.3.2.3
:Hasta ahora no he visto un compilador que se haya separado de esto.
fuente