Hay varias buenas respuestas a esta pregunta, uno de ellos ha sido aceptado. Voy a responder de todos modos con el fin de ampliar los aspectos prácticos.
Sí, es una buena práctica inicializar los punteros a NULL, así como establecer punteros a NULL después de que ya no se necesiten (es decir, se liberen).
En cualquier caso, es muy práctico poder probar un puntero antes de desreferenciarlo. Digamos que tiene una estructura que se parece a esto:
struct foo {
int counter;
unsigned char ch;
char *context;
};
A continuación, escribe una aplicación que genera varios hilos, todos los cuales operan en una sola estructura foo asignado (con seguridad) a través del uso de la exclusión mutua.
El subproceso A obtiene un bloqueo en foo, incrementa el contador y comprueba si hay un valor en ch.No encuentra uno, por lo que no asigna (ni modifica) el contexto. En cambio, almacena un valor en ch para que el hilo B pueda hacer este trabajo en su lugar.
Subproceso B Ve que el contador se ha incrementado, toma nota de un valor en ch pero no está seguro si el subproceso A ha hecho algo con el contexto. Si el contexto se inicializó como NULL, el hilo B ya no tiene que importar qué hilo A hizo, sabe que el contexto es seguro para la desreferencia (si no es NULO) o asignar (si es NULO) sin fugas.
El hilo B hace su trabajo, el hilo A lee su contexto, lo libera y luego lo reinicializa a NULO.
El mismo razonamiento se aplica a las variables globales, sin el uso de subprocesos. Es bueno poder probarlos en varias funciones antes de desreferenciarlos (o intentar asignarlos causando una fuga y un comportamiento indefinido en su programa).
Cuando se pone tonto es cuando el alcance del puntero no va más allá de una sola función. Si tiene una función única y no puede realizar un seguimiento de los punteros dentro de ella, generalmente esto significa que la función debe volver a factorizarse. Sin embargo, no hay nada de malo en inicializar un puntero en una sola función, aunque solo sea para mantener hábitos uniformes.
La única vez que he visto un caso de 'feo' de depender de un puntero inicializado (antes y después de su uso) está en algo como esto:
void my_free(void **p)
{
if (*p != NULL) {
free(*p);
*p = NULL;
}
}
No sólo se dereferencing un tipo de puntero hizo juegos de palabras mal visto en plataformas estrictas, el código anterior hace que sea aún más peligroso(), porque los que llaman tendrán algún delirio de seguridad. No puede confiar en una práctica 'al por mayor' a menos que esté seguro de que todas las operaciones están de acuerdo.
Probablemente mucha más información de la que realmente quería.
¿Cuál es tu pregunta? –
Supongo que pregunta si debería inicializar esa "cadena" a NULL (o 0), a "" o no inicializarla en absoluto. –
, requiere alguna precaución aquí, NULL es _usually_ 0 pero de acuerdo a la norma podría ser diferente: 'La NULL macro, que se define en cualquiera de, , , , , o , es una definida implementación Constante de puntero nulo C++ en esta Norma Internacional'. Definitivamente me quedaré con NULL, además de que es más "orientado a tipos" y más descriptivo en el código fuente que 0. –
RedGlyph