Foro de elhacker.net

Programación => Programación C/C++ => Mensaje iniciado por: Miky Gonzalez en 13 Julio 2013, 13:39 pm



Título: [Ayuda-C] Programación de MV; Punteros, malloc() y free()
Publicado por: Miky Gonzalez en 13 Julio 2013, 13:39 pm
Supongamos por un momento el siguiente código:

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. //#include <inttypes.h>
  5.  
  6. /* MVM - Estructura de la MV */
  7. typedef struct CPU {
  8. unsigned int inst_pointer;
  9. unsigned char *memoria;
  10. } cpu_t;
  11.  
  12. cpu_t *crear_cpu(unsigned char *memoria) {
  13. if(!memoria) return NULL;
  14. cpu_t *cpu_init = malloc(sizeof(*cpu_init));
  15. cpu_init->inst_pointer = 0;
  16.        cpu_init->memoria = memoria;
  17.  
  18. return cpu_init;
  19. }
  20.  
  21. void borrar_cpu(cpu_t *cpu) {
  22. if(!cpu) return;
  23. //void *datos = (void *)((uintptr_t)cpu);
  24. //free(datos);
  25. free(cpu);
  26. }
  27.  
  28. int main(int argc, char *argv[]) {
  29. /* Inicializar datos y comprobar argumentos */
  30. if(argc < 2) {
  31. printf("Uso: %s <archivo>\n", argv[0]);
  32. return 0;
  33. }
  34. unsigned int codigo_volumen = 100;
  35. /* Reservar el espacio necesario para almacenar
  36. * el código en memoria. Si existe, copiarlo. */
  37. unsigned char *codigo = (unsigned char *)malloc(codigo_volumen);
  38. if(!fread(codigo, 1, codigo_volumen, ARCHIVO)) {
  39. fclose(codigo_archivo);
  40. return 0;
  41. } else fclose(codigo_archivo);
  42.  
  43. cpu_t *cpu = crear_cpu(codigo);
  44. if(!cpu) return 0;
  45.  
  46. borrar_cpu(cpu);
  47. free(codigo);
  48.  
  49. return 0;
  50. }
  51.  

Faltan muchas parte del código, pero está lo esencial para mi cuestión. Explico un poco el funcionamiento:
Es una máquina virtual (¿dificil de saber?, no creo xD), en la que leo un archivo, calculo el tamaño, creo memoria dinamica para almacenar el contenido del archivo con malloc y fwrite respectivamente. Creo una variable con tipo estructura de la CPU de la MV, llamo a la funcion que me crea la CPU y le asigna el puntero. Despues libero la memoria del codigo (supuestamenta) y la de la CPU creada con la funcion crear_cpu, a través de la función borrar_cpu.
Creo que estoy utilizando mal, o los punteros, o el uso de free(). No se porqué, ni dónde, ni cómo hacerlo bien. El programa funciona correctamente, pero creo que hay fugas de memoria. ¿Podrían solventar mi problema?.


Título: Re: [Ayuda-C] Programación de MV; Punteros, malloc() y free()
Publicado por: Khronos14 en 13 Julio 2013, 19:43 pm
Puedes detectar los memory leaks con el programa Valgrind, es bastante bueno.

El código lo veo bastante bien, pero no me gustan las funciones que reservan memoria y devuelven su puntero. Es preferible que la función crear_cpu sea algo como esto:

Código
  1. int crear_cpu(cpu_t * cpu, unsigned char * memoria) {
  2. if (cpu != NULL && memoria != NULL)
  3. {
  4. cpu->inst_pointer = 0;
  5. cpu->memoria = memoria;
  6. return 1;
  7. }
  8. else
  9. return 0;
  10. }
  11.  

Entonces en el main, la utilizas así:

Código
  1. ...
  2. cpu_t cpu;
  3. if (!crear_cpu(&cpu, codigo)) return 0;
  4.  
  5. free(codigo);
  6. ...
  7.  


Título: Re: [Ayuda-C] Programación de MV; Punteros, malloc() y free()
Publicado por: amchacon en 13 Julio 2013, 23:41 pm
Krono, tu código no tiene ningun sentido (creas un objeto en la pila, despues coges un puntero de la funcion crear_cpu (¡Memory leak!)).

El error del codigo principal, es porque cpu también tiene sus punteros. Tienes que borrar esos punteros antes de borrar la cpu.


Título: Re: [Ayuda-C] Programación de MV; Punteros, malloc() y free()
Publicado por: 0xDani en 13 Julio 2013, 23:44 pm
@Khronos14, fíjate que en tu código le pasas la dirección de un objeto a una función, reservas memoria en una variable local (con lo que pierdes la dirección del objeto) y luego sales de la función. Con lo cual no haces nada.

EDIT: Se me ha adelantado @amchacon unos segundos xD


Título: Re: [Ayuda-C] Programación de MV; Punteros, malloc() y free()
Publicado por: Khronos14 en 14 Julio 2013, 01:21 am
Cierto, es que copié su código y modifiqué partes. Arreglado.

Saludos.


Título: Re: [Ayuda-C] Programación de MV; Punteros, malloc() y free()
Publicado por: 0xDani en 14 Julio 2013, 13:52 pm
Cierto, es que copié su código y modifiqué partes. Arreglado.

Saludos.

Aun así, todavía te inventas la variable cpu_init aquí:

Código
  1. int crear_cpu(cpu_t * cpu, unsigned char * memoria) {
  2. if (cpu != NULL && memoria != NULL)
  3. {
  4. cpu_init->inst_pointer = 0;
  5. cpu_init->memoria = memoria;
  6. return 1;
  7. }
  8. else
  9. return 0;
  10. }

Saludos.


Título: Re: [Ayuda-C] Programación de MV; Punteros, malloc() y free()
Publicado por: Miky Gonzalez en 14 Julio 2013, 15:26 pm
Vale he utilizado el esquema de la función crear_cpu() de Khronos, queda algo como esto, por si puede ayudar a alguien:

Código
  1. unsigned int crear_cpu(cpu_t *cpu, unsigned char *memoria) {
  2. if(!memoria || !cpu) return 0;
  3.  
  4. //memset(cpu_init->registro, 0, sizeof(cpu_init->registro) / sizeof(*cpu_init->registro));
  5. unsigned int i = 0;
  6. for(; i < 12; i++)
  7. cpu->registro[i] = 0;
  8. cpu->inst_pointer = 0;
  9. cpu->memoria = memoria;
  10.  
  11. return 1;
  12. }
  13.  

Para crear la CPU llamo a la función de la siguiente manera:

Código
  1. /* Crear CPU e inicializar los datos */
  2. cpu_t cpu;
  3. if(!crear_cpu(&cpu, codigo)) {
  4. printf("[MVM] Error al crear CPU...\n");
  5. return 0;
  6. }

Cuando tenga terminado el código es muy posible que lo postee. Tiene una buena base, así que supongo que lo continuaré y añadiré funciones de E/S, Sockets, entre otras cosas.

Gracias y saludos!