Test Foro de elhacker.net SMF 2.1

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:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//#include <inttypes.h>

/* MVM - Estructura de la MV */
typedef struct CPU {
unsigned int inst_pointer;
unsigned char *memoria;
} cpu_t;

cpu_t *crear_cpu(unsigned char *memoria) {
if(!memoria) return NULL;
cpu_t *cpu_init = malloc(sizeof(*cpu_init));
cpu_init->inst_pointer = 0;
       cpu_init->memoria = memoria;

return cpu_init;
}

void borrar_cpu(cpu_t *cpu) {
if(!cpu) return;
//void *datos = (void *)((uintptr_t)cpu);
//free(datos);
free(cpu);
}

int main(int argc, char *argv[]) {
/* Inicializar datos y comprobar argumentos */
if(argc < 2) {
printf("Uso: %s <archivo>\n", argv[0]);
return 0;
}
unsigned int codigo_volumen = 100;
/* Reservar el espacio necesario para almacenar
* el código en memoria. Si existe, copiarlo. */
unsigned char *codigo = (unsigned char *)malloc(codigo_volumen);
if(!fread(codigo, 1, codigo_volumen, ARCHIVO)) {
fclose(codigo_archivo);
return 0;
} else fclose(codigo_archivo);

cpu_t *cpu = crear_cpu(codigo);
if(!cpu) return 0;

borrar_cpu(cpu);
free(codigo);

return 0;
}


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:


int crear_cpu(cpu_t * cpu, unsigned char * memoria) {
if (cpu != NULL && memoria != NULL)
{
cpu->inst_pointer = 0;
cpu->memoria = memoria;
return 1;
}
else
return 0;
}


Entonces en el main, la utilizas así:


...
cpu_t cpu;
if (!crear_cpu(&cpu, codigo)) return 0;

free(codigo);
...
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
Cita de: Khronos14 en 14 Julio 2013, 01:21 AM
Cierto, es que copié su código y modifiqué partes. Arreglado.

Saludos.

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

int crear_cpu(cpu_t * cpu, unsigned char * memoria) {
if (cpu != NULL && memoria != NULL)
{
cpu_init->inst_pointer = 0;
cpu_init->memoria = memoria;
return 1;
}
else
return 0;
}


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:

unsigned int crear_cpu(cpu_t *cpu, unsigned char *memoria) {
if(!memoria || !cpu) return 0;

//memset(cpu_init->registro, 0, sizeof(cpu_init->registro) / sizeof(*cpu_init->registro));
unsigned int i = 0;
for(; i < 12; i++)
cpu->registro[i] = 0;
cpu->inst_pointer = 0;
cpu->memoria = memoria;

return 1;
}


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

/* Crear CPU e inicializar los datos */
cpu_t cpu;
if(!crear_cpu(&cpu, codigo)) {
printf("[MVM] Error al crear CPU...\n");
return 0;
}


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!