stringtranslate.com

Variable no inicializada

En informática , una variable no inicializada es una variable que se declara pero no se establece en un valor conocido definido antes de usarse. Tendrá algún valor, pero no predecible. Como tal, es un error de programación y una fuente común de errores en el software.

Ejemplo del lenguaje C

Una suposición común que hacen los programadores novatos es que todas las variables se establecen en un valor conocido, como cero, cuando se declaran. Si bien esto es cierto para muchos idiomas, no lo es para todos, por lo que existe la posibilidad de error. Los lenguajes como C utilizan el espacio de pila para las variables, y la colección de variables asignadas para una subrutina se conoce como marco de pila . Si bien la computadora reservará la cantidad adecuada de espacio para el marco de la pila, generalmente lo hace simplemente ajustando el valor del puntero de la pila y no establece la memoria en ningún estado nuevo (generalmente por cuestiones de eficiencia). Por lo tanto, cualquier contenido de esa memoria en ese momento aparecerá como valores iniciales de las variables que ocupan esas direcciones.

Aquí hay un ejemplo simple en C:

recuento de vacíos ( vacío ) { int k , i ; para ( yo = 0 ; yo < 10 ; yo ++ ) { k = k + 1 ; } printf ( "%d" , k ); }                         

El valor final de kno está definido. La respuesta de que debe ser 10 supone que comenzó en cero, lo que puede ser cierto o no. Tenga en cuenta que en el ejemplo, la variable ise inicializa a cero mediante la primera cláusula de la fordeclaración.

Otro ejemplo puede ser cuando se trata de estructuras . En el fragmento de código a continuación, tenemos un struct studentque contiene algunas variables que describen la información sobre un estudiante. La función register_studentpierde contenido de la memoria porque no inicializa completamente los miembros de struct student new_student. Si miramos más de cerca, al principio, agey semesterse student_numberinicializan. Pero la inicialización de los miembros first_namey last_namees incorrecta. Esto se debe a que si la longitud de las matrices de first_namecaracteres last_namees inferior a 16 bytes, durante strcpy, [1] no logramos inicializar completamente los 16 bytes completos de memoria reservados para cada uno de estos miembros. Por lo tanto, después de memcpy()enviar la estructura resultante a output, [2] filtramos algo de memoria de pila a la persona que llama.

estudiante de estructura { edad int sin signo ; semestre int sin firmar ; char nombre_nombre [ 16 ]; char apellido [ 16 ]; unsigned int número_estudiante ; };               int Register_student ( struct Student * salida , int edad , char * primer_nombre , char * apellido ) { // Si alguno de estos punteros es nulo, fallamos. if ( ! salida || ! primer_nombre || ! apellido ) { printf ( "¡Error! \n " ); devolver -1 ; }                      // Nos aseguramos de que la longitud de las cadenas sea inferior a 16 bytes (incluido el byte nulo) // para evitar desbordamientos if ( strlen ( primer_nombre ) > 15 || strlen ( apellido ) > 15 ) { printf ( " ¡ El nombre y el apellido no pueden tener más de 16 caracteres ! devolver -1 ; }               // Inicializando los miembros struct Student new_student ; Estudiante nuevo . edad = edad ; Estudiante nuevo . semestre = 1 ; Estudiante nuevo . número_estudiante = obtener_nuevo_número_estudiante (); strcpy ( nuevo_estudiante . primer_nombre , primer_nombre ); strcpy ( nuevo_estudiante . apellido , apellido );                  // copiando el resultado a la salida memcpy ( salida , & new_student , sizeof ( struct Student )); devolver 0 ; }      

En cualquier caso, incluso cuando una variable se inicializa implícitamente a un valor predeterminado como 0, este normalmente no es el valor correcto . Inicializado no significa correcto si el valor es el predeterminado. (Sin embargo, la inicialización predeterminada a es una práctica correcta para punteros y matrices de punteros, ya que los invalida antes de que realmente se inicialicen a su valor correcto). En C, las variables con duración de almacenamiento estático que no se inicializan explícitamente se inicializan a cero (o nulo, para punteros). [3]

Las variables no inicializadas no sólo son una causa frecuente de errores, sino que este tipo de errores son particularmente graves porque pueden no ser reproducibles: por ejemplo, una variable puede permanecer sin inicializar sólo en alguna rama del programa. En algunos casos, los programas con variables no inicializadas pueden incluso pasar las pruebas de software .

Impactos

Las variables no inicializadas son errores poderosos ya que pueden explotarse para perder memoria arbitraria o para lograr una sobrescritura de memoria arbitraria o para obtener la ejecución de código, según el caso. Cuando se explota un software que utiliza aleatorización del diseño del espacio de direcciones (ASLR), a menudo es necesario conocer la dirección base del software en la memoria. Se puede utilizar la explotación de una variable no inicializada para obligar al software a filtrar un puntero de su espacio de direcciones para evitar ASLR.

Uso en idiomas

Las variables no inicializadas son un problema particular en lenguajes como el lenguaje ensamblador, C y C++ , que fueron diseñados para la programación de sistemas . El desarrollo de estos lenguajes implicó una filosofía de diseño en la que los conflictos entre desempeño y seguridad generalmente se resolvían a favor del desempeño. Al programador se le asignó la carga de estar al tanto de problemas peligrosos, como variables no inicializadas.

En otros lenguajes, las variables suelen inicializarse con valores conocidos cuando se crean. Ejemplos incluyen:

Incluso en lenguajes donde se permiten variables no inicializadas, muchos compiladores intentarán identificar el uso de variables no inicializadas y reportarlas como errores en tiempo de compilación . Algunos lenguajes ayudan en esta tarea ofreciendo construcciones para manejar la inicialización de las variables; por ejemplo, C# tiene un estilo especial de parámetros de llamada por referencia a subrutinas (especificados como en lugar del habitual ), afirmando que se permite que la variable no se inicialice en el momento de la entrada, pero se inicializará después.outref

Ver también

Referencias

  1. ^ strcpy
  2. ^ memcpy()
  3. ^ "ISO/IEC 9899:TC3 (estándar C actual)" (PDF) . 2007-09-07. pag. 126 . Consultado el 26 de septiembre de 2008 .Sección 6.7.8, párrafo 10.
  4. ^ "Especificación del lenguaje Java: 4.12.5 Valores iniciales de variables". Microsistemas solares . Consultado el 18 de octubre de 2008 .

Otras lecturas