Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: AlbertoBSD en 20 Noviembre 2018, 23:20 pm



Título: ¿He liberado todos los apuntadores?
Publicado por: AlbertoBSD en 20 Noviembre 2018, 23:20 pm
Fuente: ¿He liberado todos los apuntadores? (https://programaciontrabajosescolares.blogspot.com/2018/11/he-liberado-todos-los-apuntadores.html)


Para aquellos que les guste programar con memoria dinamica en C, frecuentemente se encontraran en ocasiones tener la sensacion de no haber liberado un apuntador, esto puede ser cuando tambien trabajamos con arreglos (longitud variable) de apuntadores.

Para facilitar esta tarea se pueden programa sus propias implementaciones que lleven un conteo de cuantos apuntadores se han creado y de cuantos se han liberado.

Si al final del programa el resultado es 0, entonces pueden estar tranquilos de que todo se libero correctamente.

Esta sencilla implementacion, solo lleva dicho conteo, NO lleva conteo de memoria utilizada y/o control de cuales apuntadores ya fueron liberados, eso ya es harina de otro costal.

Código
  1. #include<stdlib.h>
  2.  
  3. unsigned int N_ptr = 0;
  4.  
  5. unsigned int test_result() {
  6. return N_ptr;
  7. }
  8.  
  9. void *test_realloc(void *ptr,size_t size) {
  10. void *ptr_new = NULL;
  11. ptr_new = realloc(ptr,size);
  12. if(ptr == NULL && ptr_new != NULL){
  13. N_ptr++;
  14. }
  15. return ptr_new;
  16. }
  17.  
  18. void *test_calloc(size_t nmemb,size_t size) {
  19. void *ptr = NULL;
  20. ptr = calloc(nmemb,size);
  21. if(ptr != NULL) {
  22. N_ptr++;
  23. }
  24. return ptr;
  25. }
  26.  
  27. void *test_malloc(size_t size) {
  28. void *ptr = NULL;
  29. ptr = malloc(size);
  30. if(ptr != NULL) {
  31. N_ptr++;
  32. }
  33. return ptr;
  34. }
  35.  
  36. int test_free(void *ptr) {
  37. N_ptr--;
  38. free(ptr);
  39. }
  40.  

Se podrian sustituir las funciones malloc, calloc, realloc y free en nuestro programa hacia estas funciones para testear y exclusivamente para prueba. posteriormente volver a dejarlas llamadas originales.

Al final del main despues de liberar todo podremos colocar esta linea

Código:
printf("Valor %i",test_result());
Si en nuestra salida del progrma el resultado es 0, significa que todo esta bien.

En caso contrareo, deberemos depurar en nuestras subfunciones el antes y el despues de cada llamada para validar en que función esta el problema.

Saludos


Título: Re: ¿He liberado todos los apuntadores?
Publicado por: CalgaryCorpus en 21 Noviembre 2018, 01:00 am
Hay, al menos, 3 cosas extrañas:

- realloc no modifica los punteros, si' libera la memoria, pero no modifica el puntero que se le pasa como primer parametro, este sigue apuntando a la zona de memoria anterior, por lo que en la linea 12, comparar ptr contra NULL no tiene sentido.

- realloc libera la memoria por uno, llamando a free(), puesto que la memoria ha sido liberada, hay que descontar 1 de tu contador, pero no lo haces. Usar realloc va a generar problemas en el contador, o bien problemas en la memoria, si es que uno decide invocar free() sobre memoria ya liberada.

- test_calloc incrementa 2 veces N_ptr, por que?


Título: Re: ¿He liberado todos los apuntadores?
Publicado por: AlbertoBSD en 21 Noviembre 2018, 01:35 am
- test_calloc incrementa 2 veces N_ptr, por que?

Si se me paso ese detalle, muchas gracias. Ya lo he editado

Lo que comentas de la linea 12, es para el caso donde Realloc fuera llamado con un apuntador a NULL, en este caso realloc funciona como malloc.

Citar
If ptr is NULL, the behavior is the same as calling malloc(new_size).

Que en la unica ocacion donde se tiene que incrementar el contador de apuntadores.

Para ese ejemplo el siguiente codigo:

Código
  1. #include<stdlib.h>
  2. #include<stdio.h>
  3.  
  4. int main() {
  5. int *lista = NULL;
  6. int i = 0;
  7. printf("Lista apunta a %p\n",lista);
  8. do {
  9. lista = realloc(lista,(i+1)*sizeof(int));//Lista solo es NULL en la primera llamada de Realloc
  10. printf("Lista apunta a %p\n",lista);
  11. lista[i] = rand();
  12. i++;
  13. }while( i < 10);
  14. free(lista);//Aqui liberamos el apuntador --
  15. }
  16.  

En caso constrario donde el ptr de parametro es distinto de NULL, no hacemos nada, ya que el apuntador ya esta contabilizado.