c++ - sencillos - punteros en c
Punteros no inicializados en el código (9)
C ++ sigue desde C en que no está diseñado para ser seguro; está diseñado para ser eficiente. Por esta razón, las variables automáticas no se inicializan. Depende de usted asegurarse de que no se utilice ningún puntero antes de inicializarlo (aunque muchos compiladores le advertirán si no inicializa sus variables)
Estoy aprendiendo C ++ y llegué a saber que los punteros si no se inicializan podrían señalar ubicaciones aleatorias en la memoria y crear problemas de que la memoria pueda ser utilizada por algún otro programa.
Ahora, si ese es el caso, nunca deberíamos tener esta línea en ninguna parte de nuestro código:
int* ptr;
En cambio, deberíamos tener algo así como
int* ptr = NULL; //Is this going to avoid the problem
Sugiero porque he visto la primera línea ( int* ptr;
) en muchos libros, así que estoy obteniendo esta duda. Si es posible, da algunos ejemplos también.
En C ++, generalmente deberías evitar todos los indicadores antiguos. Las clases de biblioteca estándar, punteros inteligentes (hasta C ++ 0x solo en varias bibliotecas como Boost o Loki) y las referencias pueden y deben usarse en la mayoría de los lugares.
Si no puede evitar los punteros, es preferible declararlos con inicializaciones, que en la mayoría de los casos no deberían ser NULL, sino el valor objetivo real, porque en C ++ puede mezclar declaraciones y expresiones libremente, por lo que solo puede y debe declarar la variable en el punto en que tiene un valor significativo para ella.
Ese no es el caso con C, donde tiene que usar punteros mucho y todas las variables deben (o tuvieron que ser anteriores a C99, no estoy exactamente seguro) ser declaradas al comienzo de un alcance. Muchas personas todavía tienen malos hábitos de C que no son apropiados para C ++.
La línea:
int* ptr;
definitivamente no está garantizado para inicializar el valor del puntero a nada en particular. La línea:
int* ptr = NULL;
Inicializará el puntero para apuntar a dirección cero, que en la práctica nunca tendrá nada útil, y que se comprobará convencionalmente como un valor de puntero no válido.
Por supuesto, todavía es posible, como lo ha dicho Doug T., intentar usar este puntero sin verificarlo y, por lo tanto, se bloqueará de todos modos.
Inicializar explícitamente en NULL tiene la ventaja de garantizar que la eliminación de referencias al puntero antes de establecerlo en algo útil se bloquee, lo que en realidad es algo bueno, ya que evita que el código funcione "accidentalmente" al tiempo que enmascara un error grave.
No es un problema hasta que se use.
Si no se utiliza el puntero, el compilador simplemente lo ignorará. Inicializarlo a NULL es lo más seguro, imho.
¿Estás seguro de que no confundes con una declaración de función? Es muy común que una función sea declarada como
char * do_something (const char * one, const char * dos);
En este caso, los punteros se utilizan para especificar qué tipo de argumento desea aprobar.
Siempre es mejor inicializar un puntero a NULL si por alguna razón no puede inicializarlo mientras se produce la declaración. Por ejemplo:
Object *ptr = new Object();
Normalmente, una función puede verificar el valor del puntero contra NULL para verificar que el puntero se haya inicializado anteriormente. Si no lo ha establecido explícitamente en NULL, y apunta a un valor aleatorio, podría eliminarse la referencia causando una segfault.
Siempre inicialice sus variables.
Ocasionalmente, es posible que desee inicializar a NULL
, pero la mayoría de las veces, debe poder inicializar el puntero al valor que se supone que debe contener . Declare las variables lo más tarde posible e inícielas en ese punto, no 15 líneas más abajo en su código.
int a,*ptr;
ahora
print(ptr,*ptr)
En el código anterior, dos casos pueden ser posibles:
Se ejecutará si el valor predeterminado en ptr no es la dirección de alguna memoria usada del programa.
Salida:
ptr *ptr eg. 0x400730 -1992206795
Dará error (falla segmentaria) si la dirección predeterminada en el ptr es la dirección de alguna memoria usada del programa. Por ejemplo, si la dirección de la variable a en la memoria también es 0x400730.
int* ptr = NULL; //Is this going to avoid the problem
Esto hará que ptr
apunte a NULL
que puede verificar explícitamente como valor predeterminado / no inicializado. Previene el problema que describes, pero un programador descuidado aún puede desreferenciar accidentalmente un puntero nulo sin verificarlo, lo que provoca un comportamiento indefinido.
La principal ventaja es su conveniencia para comprobar si el ptr
ha sido inicializado o no, en absoluto, es decir:
if (ptr != NULL)
{
// assume it points to something
}
Como esto es bastante idiomático, es bastante peligroso no inicializar el puntero a NULL
. El puntero se inicializaría en un valor no basura NULL que en realidad no apunta a nada real. Lo peor de todo es que el cheque anterior pasaría, causando problemas aún peores si sucede que la dirección en el puntero es memoria a la que puede acceder legalmente. En algunos entornos integrados, es posible que pueda acceder a cualquier parte de la memoria, por lo que puede dañar accidentalmente partes aleatorias de la memoria o partes aleatorias de su código de ejecución.