¿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?
¿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?
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 a void*
(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 es 0
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 un null 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 como 0xDEADBEEF
, 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()
o calloc()
, 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í.
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ón 0x0000000
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 a NULL
, 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
NULL pointer constant
. Hasta donde sé, no hay compiladores que lo hagan.
NULL
macro, que debe expandirse 0
en C ++ y en C 0
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.
De acuerdo con la sección del documento estándar C6.3.2.3
:
Una expresión constante entera con el valor 0, o una expresión de este tipo para escribir void *, se llama constante de puntero nulo.55) Si una constante de puntero nulo se convierte en un tipo de puntero, el puntero resultante, llamado puntero nulo, es garantizado para comparar desigual a un puntero a cualquier objeto o función.
Hasta ahora no he visto un compilador que se haya separado de esto.