Andrés Felipe Vásquez Ramírez David Mejia Restrepo
En este laboratorio ganará algún grado de familiaridad con la asignación de memoria (memory allocation). Para el caso, usted escribirá algunos programas con bugs. Luego, usará algunas herramientas para localizar los bugs que usted ha insertado. De este modo se familiarizará con algunas de estas herramientas para un uso futuro. Estas herramientas son: el debuger (gdb) y el memory-bug detector (valgrind).
Antes de empezar el laboratorio se recomienda (de manera opcional) realizar las siguientes tareas:
- Revisar los conceptos de memoria dinamica vistos previamente si no los recuerta puede acceder al siguiente enlace en el cual se encuentra la teoria.
- En la pagina del laboratorio se recolecto información sobre las herramientas gdb y valgrind, es muy basica pero mirarla y analizarla antes del laboratorio le puede ser de mucha ayuda.
- Revise y trate de entender que hacen los siguientes códigos (teniendo en cuenta la teoria vista en malloc):
Codigo 1:
#define NULL 0
int main() {
int *p = (int*)malloc(5*sizeof(int));
int array[] = {1,2,3,4,5};
printf("sizeof(p): %d\n",sizeof(p));
printf("sizeof(p): %d\n",sizeof(*p));
printf("sizeof(p): %d\n",sizeof(array));
free(p);
p = NULL;
return 0;
}
Enlace para simular.
Codigo 2:
#define NULL 0
int main() {
int *p[2];
int **q = p;
int a[] = {1,2,3};
int b[] = {4,5,6,7};
p[0] = &a[0];
p[1] = b;
*(p[0] + 2) = -1;
*(p[1] + 1) = 3;
*(*p + 1) = 10;
*(*(p + 1) + 3) = -7;
*(*q + 1) = **q + *(*q + 2);
q = q + 1;
*(*q + 1) = *(*q + 3) + *(*q + 2);
return 0;
}
Enlace para simular.
Codigo 3:
#define NULL 0
int main() {
// Reserva de memoria
int **p = (int *)malloc(2*sizeof(int *));
*p = (int)malloc(3*sizeof(int));
*(p + 1) = (int)malloc(5*sizeof(int));
// Manipulando la memoria reservada
int i;
for(i = 0; i < 3; i++) {
*(*p + i) = 2*i;
}
for(i = 0; i < 5; i++) {
if (i%2 == 0) {
*(*(p + 1) + i) = -i;
}
else {
*(*(p + 1) + i) = 0;
}
}
// Liberacion de memoria
free(*p);
free(*(p + 1));
free(p);
p = NULL;
return 0;
}
Enlace para simular
-
Escriba un programa simple llamado
null.c
que cree un puntero a un entero, llevelo a null y entonces intente desreferenciarlo (esto es, asignarle un valor). Compile este programa llamadonull
. ¿Qué pasa cuando usted ejecuta este programa? R//: Imprime Segmentation fault (core dumped), pero una vez se le asigna NULL al apuntador, cuando ejecutamos la instrucción *apuntador = 7, al no estar apuntando a nada, no puede realizar el cambio. -
Compile el programa del ejercicio anterior usando información de simbolos (con la flag -g). Al hacer esto se esta poniendo mas informacion en el ejecutable para permitir al debugger acceder a informacion util sobre los nombres de las variables y cosas similares. Ejecute el programa bajo el debugger digitando en consola (para el caso)
gdb null
y entonces una vez elgdb
este corriendo ejecuterun
. ¿Qué muestra gdb? R//: Con el comando gdb, podemos ver a mas detaller el debug del código. Y si salta un error nos muestra la linea del mismo. -
Haga uso de la herramienta
valgrind
en el programa empleado en los puntos anteriores. Se usará la herramientamemcheck
que es parte devalgrind
para analizar lo que pasa:valgrind --leak-check=yes null
. ¿Qué pasa cuando corre esto?, ¿Puede usted interpretar la salida de la herramienta anterior? R//: Se puede interprestar la salida, valgrind informa sobre un error de segmentación (Segmentation fault) en el main en la linea 6. Adicionalmente ofrece el resumen del HEAP pero en este caso está vacío. -
Escriba un programa sencillo que asigne memoria usando
malloc()
pero olvide liberarla antes de que el programa termina. ¿Qué pasa cuando este programa se ejecuta?, ¿Puede usted usar gdb para encontrar problemas como este?, ¿Que dice acerca de Valgrind (de nuevo use este con la bandera--leak check=yes
)? R//: No hay probelma con al ejecución normal del programa. Con gdb no, no informa de algun error. Ejecutando valgrind se ve una perdida de memoria, con el programa usamos malloc de tamaño 2. -
Escriba un programa que cree un array de enteros llamado data de un tamaño de 100 usando
malloc
; entonces, lleve eldata[100]
a0
. ¿Qué pasa cuando este programa se ejecuta?, ¿Qué pasa cuando se corre el programa usandovalgrind
?, ¿El programa es correcto? R//: Se nota que ejecutando con valgrind el programa hay neuvamente uan fuga de memoria, ene ste caso 1424 bytes, de igual forma la ejecución finaliza sin problema -
Codifique un programa que asigne un array de enteros (como arriba), luego lo libere, y entonces intente imprimir el valor de un elemento del array. ¿El programa corre?, ¿Que pasa cuando hace uso de
valgrind
? R//: Sí, el programa se ejecuta sin errores. Ejecutando valgrind este indica que hay un error de lectura, el cual se hace en el array que fue previamente liberado. -
Ahora pase un funny value para liberar (e.g. un puntero en la mitad del array que usted ha asignado) ¿Qué pasa?, ¿Ústed necesita herramientas para encontrar este tipo de problemas? R//: Al ejecutar el codigo tenemos un problema por un apuntador invalido y aborta la ejecución. Ejecutando valgrind se logra ver los errores puntuales del apuntador invalido y así se logra hace run inicio de debugg
-
Intente usar alguna de las otras interfaces para asignacion de memoria. Por ejemplo, cree una estructura de datos simple similar a un vector y que use rutinas que usen realloc para manejar el vector. Use un array para almacenar los elementos del vector; cuando un usuario agregue una entrada al vector, use realloc para asignar un espacio mas a este. ¿Que tan bien funciona el vector asi?, ¿Como se compara con una lista enlazada?, utilice
valgrind
para ayudarse en la busqueda de errores. -
Gaste mas tiempo y lea sobre el uso de gdb y valgrind. Conocer estas herramientas es critico; gaste el tiempo y aprenda como volverse un experto debugger en UNIX y C enviroment.
- http://valgrind.org/docs/manual/quick-start.html
- http://www.st.ewi.tudelft.nl/koen/ti2725-c/valgrind.pdf
- http://pages.cs.wisc.edu/~bart/537/valgrind.html
- http://web.mit.edu/amcp/drg/valgrind-howto.pdf
- http://www.lsi.us.es/~javierj/ssoo_ficheros/GuiaGDB.htm
- https://www.gdb-tutorial.net/
- https://web.eecs.umich.edu/~sugih/pointers/summary.html
- https://www.cs.umd.edu/~srhuang/teaching/cmsc212/gdb-tutorial-handout.pdf
- https://lihuen.linti.unlp.edu.ar/index.php/C%C3%B3mo_usar_GDB
- https://www.cs.cmu.edu/~gilpin/tutorial/
- http://pages.di.unipi.it/bodei/CORSO_FP_17/FP/Lezioni/gdb-commands.pdf
- https://cs.brown.edu/courses/cs033/docs/guides/gdb.pdf
- https://darkdust.net/files/GDB%20Cheat%20Sheet.pdf
- http://users.ece.utexas.edu/~adnan/gdb-refcard.pdf