NULO (C)

NULL en los lenguajes de programación C y C++  es una macro declarada en el archivo de encabezado stddef.h (y otros archivos de encabezado). El valor de esta macro es una constante de puntero nulo dependiente de la implementación . 

Una constante de puntero nulo es una expresión constante de entero con valor 0 o (solo en C) la misma expresión convertida en type void*. Una conversión constante de puntero nulo a cualquier tipo de puntero es un puntero nulo . Se garantiza que un puntero nulo no es igual a un puntero a cualquier objeto (en el sentido más amplio, cualquier dato) o función. Se garantiza que dos punteros nulos cualesquiera sean iguales. La desreferenciación de un puntero nulo es una operación con un comportamiento indefinido .

En otras palabras, la implementación proporciona un valor especial: una constante de puntero nulo, que se puede asignar a cualquier puntero y dicho puntero, cuando se compara, no será igual a ningún puntero "correcto". Es decir, podemos suponer que un puntero nulo no contiene una dirección válida en la memoria.

Usos

Los punteros nulos están diseñados como una forma conveniente de "marcar" punteros que no se sabe que apuntan a una dirección de memoria válida. Por ejemplo, al declarar un puntero como una variable automática, su valor no está definido. Para tener en cuenta que este puntero aún no contiene una dirección válida en la memoria, a dicho puntero se le asigna una constante de puntero nulo:

vacío f ( vacío ) { int * x = NULL ; /* ... */ }

Es un buen estilo de programación asignar un puntero nulo a un puntero después de liberar la memoria a la que hace referencia. Además, el uso de punteros de puesta a cero es relevante para la seguridad de liberar memoria: la operación de eliminación en C++ ( free en C) es segura para un puntero nulo. Por ejemplo:

TIPO * foo = nuevo TIPO (); // usa foo delete foo ; // foo != NULL // algún código de programa borra foo ; //¡ERROR! la memoria ya no está disponible

mientras que en esta versión no habrá error

TIPO * foo = nuevo TIPO (); // usa foo delete foo ; // foo != NULL foo = NULL ; // foo == NULL // algún código de programa borra foo ; //sin error: eliminar comprueba el valor de foo

Dimensiones del puntero

Al llamar a una función, se puede pasar NULL a uno de los argumentos. La macro NULL se puede definir de diferentes maneras en diferentes compiladores, incluyendo

#define NULL 0

#define NULL ((void *)0)

En el primer caso, NULL es de tipo int, y en el segundo caso, es de tipo void*. Hay arquitecturas donde sizeof(int) != sizeof(void*), entonces en diferentes plataformas la función recibirá una cantidad diferente de bytes, lo que puede interrumpir su funcionamiento. Actualmente se está intentando resolver este problema en C mediante la introducción de nullptr, consulte la propuesta N 2394 [1] .

Desreferenciación de punteros nulos

La desreferenciación de un puntero nulo es una operación con un comportamiento indefinido . No se imponen restricciones a la implementación : por ejemplo, puede ocurrir un acceso a la memoria que no está destinado a ser utilizado por este programa (es decir, al leer, se leerá "basura", y al escribir, el valor se escribirá en un área de memoria que no pertenece al programa). Por ejemplo, en DOS, escribir en la dirección cero sobrescribirá al menos el vector de interrupción cero , por lo que la siguiente llamada a int 0 probablemente bloqueará el sistema. Sin embargo, esto suele dar como resultado un error en tiempo de ejecución (si el sistema operativo implementa protección de memoria y se bloquea el acceso a la memoria no asignada para el proceso). Por ejemplo, en Windows 9x , el mensaje "Falla de protección general" - "El programa realizó una operación ilegal y se cerrará" ( falla de protección general en inglés  , GPF ) se emite con mayor frecuencia en los casos en que el programa accede a la memoria de acuerdo con incorrectamente ( incluido el puntero no inicializado o ya liberado). En sistemas operativos similares a Unix , en tales situaciones, el proceso recibe una señal SIGSEGV y su controlador imprime el mensaje " Error de segmentación ".

Punteros nulos en C++

Si toma una implementación específica de NULL en los archivos fuente, puede definirse como (void*)0 o como 0. El uso de NULL en proyectos de C++ puede generar errores. Por ejemplo

int ( NombreClase ::* pf )() = NULL ;

dará como resultado un error de compilación si NULL se define como (void*)0 (por ejemplo, se incluyó indirectamente un encabezado donde se superpone la definición estándar de C++ de NULL). Por lo tanto, no se recomienda usar NULL en la forma ((void *)0) en programas C++. El estándar C++11 agrega una nueva palabra clave nullptr [2] [3] para indicar un puntero nulo .

Véase también

Notas

  1. N   2394 _ . Estándares abiertos . Consultado el 22 de mayo de 2020. Archivado desde el original el 27 de julio de 2020.
  2. JTC1/SC22/WG21 - Comité de estándares de C++. SC22/WG21/N2431 = J16/07-0301 "Un nombre para el puntero nulo: nullptr"  (inglés) (PDF)  (enlace no disponible) . JTC1.22.32 . Comité de estándares de C++ (2 de octubre de 2007). Fecha de acceso: 4 de octubre de 2010. Archivado desde el original el 11 de febrero de 2012.  (Inglés)
  3. Scott Meyers , Resumen de la disponibilidad de características de C++11 en gcc y MSVC Archivado el 26 de octubre de 2011 en Wayback Machine , 16 de agosto de 2011

Enlaces