Accesos no válidos
Accesos fuera de límites y datos sin inicializar
Accesos no válidos es una lección gratuita de C Academy en CoddyKit. Esta es la lección 3 de 4. Puedes leer la lección completa abajo gratuitamente — luego la practicas en el navegador con un editor de código integrado y un tutor de IA 24/7. Forma parte de la ruta de aprendizaje de C Academy, y tu progreso se sincroniza en la web y la app de CoddyKit. El curso de C Academy incluye 4 lecciones en total.
Más allá de las fugas
Las fugas desperdician memoria, pero los errores de acceso no válido la corrompen. memcheck detecta varios tipos:
- Leer o escribir más allá del final de un búfer
- Usar memoria después de
free - Leer valores no inicializados
- Leer o escribir mediante un puntero incorrecto
Estos errores provocan los fallos más peligrosos y difíciles de reproducir.
Escritura fuera de los límites
Esto asigna espacio para 5 enteros, pero escribe en el índice 5, la sexta posición.
El índice 5 está un elemento más allá del final. memcheck informa de una Invalid write of size 4 en esta línea.
#include <stdlib.h>
int main(void) {
int *a = malloc(5 * sizeof(int));
a[5] = 99; /* valid indices are 0..4 */
free(a);
return 0;
}Interpretar el error
El informe indica la operación, el tamaño y la relación con el bloque:
Invalid write of size 4Address 0x... is 0 bytes after a block of size 20 alloc'd
«0 bytes after a block of size 20» indica que el acceso se produjo justo después de una asignación de 20 bytes (5 enteros).
Lectura fuera de los límites
Las lecturas también se detectan. En este caso, el bucle avanza un elemento de más.
memcheck señala una Invalid read of size 4 en la iteración final, aunque el programa podría «funcionar» por casualidad.
#include <stdlib.h>
#include <stdio.h>
int main(void) {
int *a = calloc(3, sizeof(int));
for (int i = 0; i <= 3; i++) /* should be i < 3 */
printf("%d\n", a[i]);
free(a);
return 0;
}Valores no inicializados
malloc no pone a cero la memoria. Usarla antes de asignarle un valor produce un valor impredecible.
memcheck informa de Conditional jump or move depends on uninitialised value(s) cuando dicho valor afecta al flujo de control o a la salida.
#include <stdlib.h>
#include <stdio.h>
int main(void) {
int *p = malloc(sizeof(int));
if (*p == 0) /* *p was never set */
printf("zero\n");
free(p);
return 0;
}Por qué se retrasan los informes de valores no inicializados
memcheck no avisa en el mismo instante en que lee memoria no inicializada. Realiza un seguimiento de si los valores están «definidos» y solo informa cuando un valor indefinido realmente importa, por ejemplo, en una rama, una salida o una llamada al sistema.
Así se evitan falsas alarmas cuando se copian bytes no inicializados sin consecuencias.
Uso después de liberar
Tocar la memoria después de liberarla es un comportamiento indefinido. memcheck lo detecta con precisión.
Informa de Invalid read of size 4 con la nota Address ... is 0 bytes inside a block of size 4 free'd, e incluso muestra dónde se produjo el free.
#include <stdlib.h>
#include <stdio.h>
int main(void) {
int *p = malloc(sizeof(int));
*p = 7;
free(p);
printf("%d\n", *p); /* read after free */
return 0;
}Doble liberación
Liberar el mismo puntero dos veces corrompe la contabilidad interna del asignador.
memcheck informa de Invalid free() y muestra tanto la liberación actual como la asignación original, lo que hace evidente el error.
#include <stdlib.h>
int main(void) {
int *p = malloc(sizeof(int));
free(p);
free(p); /* freed twice */
return 0;
}Rastrear los orígenes
Para los errores causados por valores no inicializados, añada --track-origins=yes.
memcheck informará entonces de dónde se creó el valor incorrecto, no solo de dónde se utilizó, convirtiendo una advertencia imprecisa en una corrección concreta.
valgrind --track-origins=yes ./progPila y variables globales
memcheck es excelente para detectar errores en el heap. Para los desbordamientos en la pila o en matrices globales, su cobertura es menor.
En esos casos, AddressSanitizer (gcc -fsanitize=address) suele ser una opción más adecuada. Ambas herramientas se complementan.
Desfase de uno: el terminador nulo
Un desbordamiento frecuente del heap consiste en olvidar el terminador de cadena. strlen devuelve 5 para 'hello', pero la cadena necesita 6 bytes para almacenar el '\0' final.
memcheck informa de una escritura inválida cuando strcpy escribe ese último byte más allá del final.
#include <stdlib.h>
#include <string.h>
int main(void) {
char *s = malloc(strlen("hello")); /* needs +1 */
strcpy(s, "hello"); /* writes the '\0' past end */
free(s);
return 0;
}Comprobación rápida
Identifique qué informa memcheck para el fragmento de código.
Resumen
Ahora puede detectar errores de acceso no válidos:
- Las lecturas y escrituras fuera de los límites aparecen como Invalid read/write, junto con el desplazamiento dentro del bloque
- Los valores no inicializados se señalan cuando afectan a una decisión o a una salida
- Se detectan el uso después de liberar y la doble liberación, con ambos puntos de llamada
--track-origins=yesidentifica el origen de los valores indefinidos; combínelo con ASan para los errores de la pila
Siguiente: leer el informe completo.
Preguntas frecuentes
¿La lección «Accesos no válidos» es gratis?
Sí — el texto completo de «Accesos no válidos» es gratis para leer aquí en la web. Para practicarla de forma interactiva (editor de código integrado y tutor de IA 24/7) y desbloquear el resto del curso de C Academy, actualiza a CoddyKit PRO. El curso de C Academy incluye 4 lecciones en total.
¿Qué aprenderé en «Accesos no válidos»?
Accesos fuera de límites y datos sin inicializar Practicas C Academy con código real que ejecutas directamente en el navegador, y un tutor de IA 24/7 responde tus preguntas mientras trabajas en la lección.
¿Necesito experiencia previa para empezar C Academy?
No se requiere experiencia previa. C Academy en CoddyKit está estructurado para principiantes hasta estudiantes avanzados, así que puedes empezar aquí o desde el inicio y avanzar a tu ritmo. Esta es la lección 3 de 4.
¿Cuánto tiempo toma la lección «Accesos no válidos»?
La mayoría de las lecciones de CoddyKit toman alrededor de 5–10 minutos. Cada una es compacta e interactiva, así que avanzas constantemente y retomas exactamente por donde dejaste en la web y la app.
¿Puedo escribir y ejecutar código en esta lección de C Academy?
Sí. Cada lección de C Academy incluye un editor de código integrado, así que escribes y ejecutas código real directamente en tu navegador y obtienes retroalimentación instantánea de IA — sin configuración local necesaria.
Todas las lecciones de este curso
- Por qué usar Valgrind
- Detección de fugas
- Accesos no válidos
- Lectura de informes