Leamos su código línea por línea:
Línea 3: le pide al sistema operativo que asigne 5 bytes de memoria y almacene el puntero al primer byte en la variable a
.
Línea 4: intenta leer la memoria 5 bytes después del byte apuntado a la dirección contenida en a
variable. ¡Pero debes recordar cómo funcionan los índices en C! Cuando accede a la tab[0]
, donde la pestaña representa una matriz (o un puntero, realmente no nos importa porque en C se pueden rastrear de la misma manera), en realidad está accediendo al primer elemento de la matriz correspondiente. Al preguntar por el valor de a[5]
, en realidad está preguntando por el valor del sexto elemento de su matriz declarada dinámicamente. Pero en realidad, no reservó espacio para este elemento, porque en la línea 3 asignó 5 bytes, o una matriz de 5 elementos, no 6. La lectura / escritura fuera de la memoria que asignó tiene un comportamiento indefinido, lo que significa que básicamente todo puede suceder: nada o una falla de segmentación. Copié / pegué el código (agregué los encabezados correspondientes para que funcionara) y para mí funcionó como se esperaba, pero aún así había escrito en un punto de memoria no asignado.
- ¿Cuál es el algoritmo utilizado por el IRCTC para reservar en línea?
- ¿Cómo diseñaría un algoritmo para clasificar 100 millones de libros y encontrar duplicados funcionales?
- ¿Cuál es la diferencia entre [matemáticas] 2 ^ {n ^ {o (1)}} [/ matemáticas] y [matemáticas] 2 ^ {O (n ^ e)} [/ matemáticas] (para algunos e <1)?
- ¿Qué es la búsqueda de fuerza bruta?
- Cómo generar una clave privada en el algoritmo RSA
Eres verdadero cuando dices que debes free
algo que malloc
. En realidad, no permanecerá en su computadora hasta que reinicie, porque los sistemas operativos modernos pueden rastrear toda la memoria utilizada por un programa determinado y liberar cada espacio utilizado por un programa después de que se detiene. Sin embargo, cada asignación no liberada es memoria desperdiciada para la ejecución actual del programa, por lo que sigue siendo muy importante liberar la memoria asignada dinámicamente justo cuando ya no la necesite.
Ahora, hablemos de lo que quieres lograr. Por lo que entendí, estás tratando de:
- Asignar memoria dinámicamente
- Escribir en esa memoria asignada dinámicamente
- Leyendo una cuerda
Acabamos de hablar sobre la asignación dinámica de memoria y la lectura / escritura en memoria, y creo que todo debería estar claro en este momento. Para resumir, debe asignar memoria tanto como la necesite, y debe asegurarse, como programador, de nunca tener que leer fuera de ese espacio dado.
Ahora, intenta imprimir esa cadena, con printf
. Como habrás notado, cuando imprimes la cadena, nunca escribes en ningún lado cuánto dura la cadena para imprimir. La función printf
no sabe cuánto dura tu matriz de caracteres, incluso si declaraste tu variable como char a[10];
(en este nivel, no puede tener un nivel de introspección tan grande como para que la variable sea una cadena de longitud 9 (sí, ¡dije 9! sigue leyendo)). Es por eso que debe poner un \0
al final de la cadena, ya que como no tenemos la longitud de la cadena, la función printf
aún debe saber cuándo dejar de leer el siguiente elemento de la matriz (como un ¡array es una especie de puntero y, por lo tanto, no tiene una longitud!). Esta restricción de ese carácter nulo final implica dos cosas:
- Nunca olvide agregar el carácter nulo; de lo contrario,
printf
u otras funciones basadas en cadenas nunca dejarán de repetir, siempre leyendo e imprimiendo el siguiente elemento de la matriz a menos que intente leer fuera de la memoria reservada del programa (¡lo que provocará un bloqueo! ) - Cuando asigne un número fijo de bytes para una cadena, no olvide asignar un byte adicional para ese carácter nulo. Por ejemplo, si desea tener una cadena de 5 caracteres imprimibles (para almacenar la cadena de
hello
, 5 caracteres imprimibles), tendrá que asignar 6 bytes, debido a ese carácter nulo final.
En el futuro, cuando tenga algunos programas en C y no sepa por qué se bloquea (o al menos, no sabe en qué parte del código se bloquea), use Valgrind. Le indica en qué función se produjo un error de lectura / escritura de memoria y tiene muchas otras herramientas de seguimiento de errores. Incluso no necesita un tutorial completo para saber cómo usarlo, simplemente ejecute valgrind
y le dará todo lo que necesita en la salida.
Algunos enlaces sobre lo que hablamos aquí:
¿Qué pasa REALMENTE cuando no liberas después de Malloc?
¿Qué tan peligroso es acceder a una matriz fuera de los límites?
Valgrind