[Ayuda-C] Programación de MV; Punteros, malloc() y free()

Iniciado por Miky Gonzalez, 13 Julio 2013, 13:39 PM

0 Miembros y 1 Visitante están viendo este tema.

Miky Gonzalez

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?.
Mi blog personal, con información acerca de programación, seguridad, desarrollo y electrónica:

EN CONSTRUCCIÓN

Khronos14

#1
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);
...

amchacon

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.
Por favor, no me manden MP con dudas. Usen el foro, gracias.

¡Visita mi programa estrella!

Rar File Missing: Esteganografía en un Rar

0xDani

#3
@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
I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM

Khronos14

Cierto, es que copié su código y modifiqué partes. Arreglado.

Saludos.

0xDani

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.
I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM

Miky Gonzalez

#6
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!
Mi blog personal, con información acerca de programación, seguridad, desarrollo y electrónica:

EN CONSTRUCCIÓN