elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Buscar Ingresar Registrarse
29 Mayo 2012, 00:48  


Tema destacado: Suscripción al boletín mensual de elhacker.net

+  Foro de elhacker.net
|-+  Programación
| |-+  Programación C/C++ (Moderadores: Eternal Idol, Littlehorse)
| | |-+  Comprobar si libere o no memoria dinamica(SOLUCIONADO)
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] 2 Ir Abajo Respuesta Imprimir
Autor Tema: Comprobar si libere o no memoria dinamica(SOLUCIONADO)  (Leído 2,715 veces)
^Tifa^


Desconectado Desconectado

Mensajes: 2.802


Ver Perfil
Comprobar si libere o no memoria dinamica(SOLUCIONADO)
« en: 11 Noviembre 2008, 14:40 »

Hola.

Tengo una pregunta que hacer, espero que no se la encuentren demasiado ignorante, pero es una duda  :huh:

Cuando vamos a reservar memoria dinamica en C procedemos siempre a hacer esto cierto ::

variable = malloc(100*sizeof(variable));

if ( variable == 0 ) {
puts("No se reservo la memoria requerida");
}

Ok.. perfecto lo anterior se entiende.. entonces imaginemos que termina la aplicacion y libero :

free(variable);

Y despues de la sentencia anterior hago nuevamente esto ::

if ( variable == 0 ) {
puts("Memoria Liberada");
} else {
puts("Aun tengo algo reservado");
}

Aqui lo que ocurre es que siempre se me cumple la segunda secuencia la de
"Aun tengo algo reservado" Y la variable en si no esta inicializada con ningun valor por ende me imprime una rara direccion virtual de memoria o codigo basura como dicen algunos... yo quiero saber, entonces como verifico realmente que dicha variable libero la memoria??? porque si evaluandola a cero o NULL comprobamos si reservo o no, no deberia darme como verdadero despues que la libero con free???


« Última modificación: 12 Noviembre 2008, 16:15 por ^TiFa^ » En línea
ҒrεακΠιи∂

Desconectado Desconectado

Mensajes: 184



Ver Perfil
Re: Comprobar si libere o no memoria dinamica..
« Respuesta #1 en: 11 Noviembre 2008, 15:09 »

Buenas

La funcion free() hace que esa porcion de memoria que reservaste vuelva al "pool" comun de la app, pero el puntero sigue apuntando a la misma porcion de memoria.
Por eso es que siempre cumple la 2da condicion.

Solucion: Debajo de cada free(), asignale NULL al puntero

Salu2, FreakMind


En línea

Connoisseurs of C semantics find C++ inferior to ++C
^Tifa^


Desconectado Desconectado

Mensajes: 2.802


Ver Perfil
Re: Comprobar si libere o no memoria dinamica..
« Respuesta #2 en: 11 Noviembre 2008, 22:08 »

Entonces, si el puntero siempre va a apuntar a una direccion de memoria este jamas valdra cero o NULL cual sea el caso  :¬¬

Por ende si nunca vale cero o NULL desde su declaracion, es un poco corto usar esto ::

puntero = malloc(1000*sizeof(puntero));

puntero == NULL ? puts("No se reservo") : puts("Se reservo");

Porque si nunca vale cero.. por ende como verifico realmente que asigno el espacio que el dice que asigno??? Y como verifico despues de usar free que realmente lo libero ???

Ok, puedo inicializar la variable asi

puntero = 0;

pero porque?? Si esto funciona asi, porque no se ha explico con anterioridad que se utilize asi?
En línea
Flakito81


Desconectado Desconectado

Mensajes: 508



Ver Perfil
Re: Comprobar si libere o no memoria dinamica..
« Respuesta #3 en: 11 Noviembre 2008, 22:14 »

Lo sabes xq malloc te retorna el espacio adjudicado o NULL si no se pudo realizar la reserva de memoria.
En línea
^Tifa^


Desconectado Desconectado

Mensajes: 2.802


Ver Perfil
Re: Comprobar si libere o no memoria dinamica..
« Respuesta #4 en: 11 Noviembre 2008, 22:39 »

Entonces si malloc funciona asi.. No puede free retornar NULL cuando se le llama???

Lo he hecho de varias maneras... y todavia llevo dudas, disculpen mi ignorancia. Pero quiero algo que cuando yo libere y lo compare con NULL o Cero me diga que si que efectivamente esta vacia.

Código:
void funcion(int **numero);


int main()
{

int *puntero;

fprintf(stdout, "Mi reserva es %d\n", puntero);

if((puntero = malloc(100)) == NULL ) {
fprintf(stdout, "No se reservo la memoria\n");
} else {
fprintf(stdout, "Se reservo la memoria\n");
}

fprintf(stdout, "Mi reserva es %d\n", puntero);

funcion(&puntero);


EXIT_SUCCESS;
}

void funcion (int **numero) {

fprintf(stdout, "Mi reserva es %d\n", numero);

free(*numero);

if ( *numero == NULL || *numero == 0 ) {
fprintf(stdout, "Se libero la memoria\n");
} else {
fprintf(stdout, "No se libero\n");
}

fprintf(stdout, "Mi reserva es %d\n", numero);

}
« Última modificación: 11 Noviembre 2008, 22:45 por ^TiFa^ » En línea
^Tifa^


Desconectado Desconectado

Mensajes: 2.802


Ver Perfil
Re: Comprobar si libere o no memoria dinamica..
« Respuesta #5 en: 11 Noviembre 2008, 22:42 »

Se repitio el post 2 veces perdon  :P
« Última modificación: 11 Noviembre 2008, 22:44 por ^TiFa^ » En línea
Anibal784


Desconectado Desconectado

Mensajes: 762

Yo no la vote, pero me la tengo que aguantar igual


Ver Perfil WWW
Re: Comprobar si libere o no memoria dinamica..
« Respuesta #6 en: 11 Noviembre 2008, 23:44 »

Lo que pasa es que tenés que confiar en que free libera la memoria, si no te gusta deberías empezar a ver cómo hace free para liberar o implementar por tu cuenta un free y ahí empezar a confiar en que el sistema operativo es el que libera realmente la memoria.

    free no puede poner a NULL tu puntero porque recibe por copia el puntero (si no me equivoco la firma de free sería void free(void*) ), si bien dentro de la función puede asignar NULL al puntero, cuando sale ese valor se pierde (es como cuando hacés una función que recibe 2 enteros, vos adentro podés jugar con esos enteros que tu variable original no se modifica). Ahora, supongamos que vos confiás en que free siempre libera la memoria y que hace bien su trabajo (es lo que deberías hacer) pero necesitás comprobar que el puntero sea NULL, lo que hacés es una función mao meno así:
Código
void liberar(void **ptr){
   free(*ptr);
   *ptr = NULL;
}
 
pero es bastante, por decirlo así, al pedo hacer eso ya que no hace mucho, lo que lográs es que vos dentro de esa función podés hacer un montón de otras cosas, como guardar la posición de memoria liberada, o crearte una estructura y manejar conteo o extenderlas (siempre y cuando reimplemente mallo, calloc y realloc). En si free por si sóla no da ninguna certeza de que hizo realmente su trabajo (por lo menos lo que yo se).
En línea

El que llega sin que lo llamen, se va sin que lo echen.

Citar
Vos no la votaste por eso la tenes adentro.
Lo fino no es lo tuyo, y a mi me chupa un huevo, soy argentino y no peronista, y eso es lo que realmente te molesta.
dooque

Desconectado Desconectado

Mensajes: 149



Ver Perfil
Re: Comprobar si libere o no memoria dinamica..
« Respuesta #7 en: 12 Noviembre 2008, 01:07 »

pero es bastante, por decirlo así, al pedo hacer eso ya que no hace mucho, lo que lográs es que vos dentro de esa función podés hacer un montón de otras cosas, como guardar la posición de memoria liberada, o crearte una estructura y manejar conteo o extenderlas (siempre y cuando reimplemente mallo, calloc y realloc). En si free por si sóla no da ninguna certeza de que hizo realmente su trabajo (por lo menos lo que yo se).

Hola! Tengo dos cosas para acotar al tema!

1) Si no confias en "free()" ya es grave! jajajaja! MUY GRAVE! jajaja!!
2) Y la mas importante creo es que despues de hacer un "free()" de cualquier puntero es ALTAMENTE RECOMENDABLE asignarle NULL para que no quede apuntando a posiciones de memoria q mas adelante puedes pisar! he escuchado una tesis al respecto y he visto como sucumben grandes programas por causa de esto asi q como pequeña moraleja (o no tan pequeña) "Es bueno tener la costumbre q despues de liberar un puntero asignarlo a NULL"
Otro efecto parecido tiene el hecho de declarar variables y no inicializarlas en el mismo momento! puedes romper facilmente programas asi y ni darte cuenta!! bueno ya flashie mucho!!

Saludos!!
En línea
^Tifa^


Desconectado Desconectado

Mensajes: 2.802


Ver Perfil
Re: Comprobar si libere o no memoria dinamica..
« Respuesta #8 en: 12 Noviembre 2008, 13:40 »

Hola nuevamente.

Citar
1) Si no confias en "free()" ya es grave! jajajaja! MUY GRAVE! jajaja!!

Entonces dame una razon 'logica' por la cual deba ciegamente confiar en el funcionamiento de esta y de malloc, porque yo expongo mis dudas y con ejemplos del porque estoy dudosa con estas 2 funciones... y aparentemente todos entienden mis ejemplos, pero nadie aun me ha dado una explicacion nociva y con ejemplos sobre porque debo simplemente 'confiar'.


A lo mejor estoy en una ignorancia enorme, pero jamas he visto en ningun libro de C o C++ que se diga que despues de liberar memoria con free hay que asignarle NULL o cero a un puntero... Jamas he visto eso. Y si esto es asi, entonces la funcion free no es efectiva y no hace su trabajo que se supone que ha de hacer... o lo hace a otro nivel que desconozco ya sea a nivel mas profundo o de hardware que no puedo comprobar su efectividad con simples funciones tipo printf...

Incluse fui mas lejos, intente asignarle cero con malloc a mi puntero :

if ((puntero = malloc(0)) == 0) {
printf("No se reservo");
} else {
print("Se reservo");
}

Y adivinen cual secuencia me responde? La segunda... "Se reservo". Sin embargo si asigno directamente cero a la variable puntero y lo igualo a cero ahi se cumple la primera :

if ((puntero = 0)== 0) {
printf("No se reservo");
} else {
print("Se reservo");
}

Aqui es efectiva la primera seleccion "No se reservo"... O malloc y free trabajan a un nivel mas bajo del normal y para comprobar de lleno lo que hacen no basta con usar printf o compararlas con cero o NULL, o todo este tiempo se ha estado enganando a todo el mundo con el funcionamiento de ambas funciones  :¬¬

A lo mejor alguien que conozca mucho sobre Assembly y C puede darme una explicacion mas logica sobre este hecho, porque aun tengo vacios en cuanto a esta relacion.

Tampoco conozco a nadie que sin inicializar una variable a un valor la utilize en su programa para algo o sea seria ignorancia de cualquier programador hacer algo tipo :

int variable;

printf("El resultado es %d\n", (variable*5));

Ahi es una falla grave de la logia del programador, no del funcionamiento del lenguaje en si.

« Última modificación: 12 Noviembre 2008, 13:43 por ^TiFa^ » En línea
Anibal784


Desconectado Desconectado

Mensajes: 762

Yo no la vote, pero me la tengo que aguantar igual


Ver Perfil WWW
Re: Comprobar si libere o no memoria dinamica..
« Respuesta #9 en: 12 Noviembre 2008, 14:16 »

free y [m|c|r]alloc son funciones del standard, eso significa que cada compilador hace su implementación de esas funciones, si no te agrada, no hace falta saber assembler sólo conocer cómo maneja tu sistema operativo la memoria y generar tu free y [m|c|r]alloc, ahora tampoco confiás en el manejo de memoria de tu sistema operativo, vas a tener que ensuciarte las manos y entrar a hacer tu propio manejador de memoria (cosa que en un sistema de código abierto ya es difícil, imaginate en uno que no proporciona el código). Dado la concepción de free es imposible que te retorne algo para que vos veas realmente si liberó o no la porción de memoria (a eso tenés que sumarle que el menejo de memoria dentro del sistema operativo es complicado, hasta el punto de hacerle creer al proceso que tiene 4Gb de memoria continua para el solo, cuando en realidad sólo tiene cargado 100k el resto está en el disco y lo más probable que esos 100k no sean continuos), es más si vos querés saber algo tenés que preguntarle al kernel y ¿adiviná qué? tenés que confiar en lo que el kernel te diga.

    bueno, volviendo al tema, capaz que la implementación de free (tal como vos decís) no libera realmente la memoria, sino que guarda dentro de una estuctura información de que se pidió esa cantidad de memoria y que ahora está libre, entonces cuando vos pedís la misma cantidad se saltea al kernel y te retorna ese mismo espacio, a lo que quiero llegar es que lo que hace free a lo mejor no es liberar memoria sino que te dice no tenés más disponible esa memoria.
« Última modificación: 12 Noviembre 2008, 14:19 por Anibal784 » En línea

El que llega sin que lo llamen, se va sin que lo echen.

Citar
Vos no la votaste por eso la tenes adentro.
Lo fino no es lo tuyo, y a mi me chupa un huevo, soy argentino y no peronista, y eso es lo que realmente te molesta.
Karman


Desconectado Desconectado

Mensajes: 657



Ver Perfil WWW
Re: Comprobar si libere o no memoria dinamica..
« Respuesta #10 en: 12 Noviembre 2008, 14:17 »

no entiendo mucho lo que quieres hacer pero: el resultado de malloc(0) no está completamente definido (en realidad si pero no está implementado de la misma forma en todos los compiladores), depende del compilador, en algunos casos retornará NULL, y en otros retornará un puntero a la cima (heap) de la memoria "solicitable". de todas formas hacer esto:

if ((puntero = 0)== 0)

es más que obvio su resultado, con respecto a lo de free, free está definida para ser VOID, de modo que no puede modificar el valor del puntero que libera, y la liberación queda en manos del SO, por lo que se realice con el espacio de memoria depende del SO, en algunos casos el espacio de memoria simplemente se marca como libre (no se libera) para que en futuras llamadas a malloc sea reutilizado.

como dato aclarativo, tanto malloc como free dependen del SO que se utilice, así que tendrías que buscar en la ayuda del SO que utilices para tener más información...

S2
En línea

dooque

Desconectado Desconectado

Mensajes: 149



Ver Perfil
Re: Comprobar si libere o no memoria dinamica..
« Respuesta #11 en: 12 Noviembre 2008, 14:51 »

Aver... no si entiendo tus dudas pero a ver si esto te aclara un poco las cosas!

Por un lado...
C esta echo para manejar cosas de bajo niven sin usar asm, tiene las cosas basicas y necesarias y nada mas, todo el resto lo tiene q hacer el programador, esto tiene sus ventajas y desventajas... Una de esas cosas que tiene que hacer el programador es llevar la cuenta de la memoria que usa para que so programano tenga "Memory Leaks".

Por el otro...
Para el manejo dinamico de memoria C te brinda 4 funciones:

void * calloc(size_t nmemb, size_t size);
void * malloc(size_t size);
void    free(void *ptr);
void * realloc(void *ptr, size_t size);

Ver... http://www.poplog.org/docs/popdocs/pop11/unix/malloc


Bien! ahora...

Citar
Entonces dame una razon 'logica' por la cual deba ciegamente confiar en el funcionamiento de esta y de malloc, porque yo expongo mis dudas y con ejemplos del porque estoy dudosa con estas 2 funciones... y aparentemente todos entienden mis ejemplos, pero nadie aun me ha dado una explicacion nociva y con ejemplos sobre porque debo simplemente 'confiar'.
Estas funciones (malloc/calloc) lo que hacen es hacer las llamadas al sistema correspondiente que le permiten al sistema operativo asignarle memoria a un proceso! po otro lado "free" hacela llamadaal sistema para devolverle memoria "que no va a usar" o "que ya no necesita" por decirlo de alguna manera! Si estas funciones no fueran confiebles habriamiles o millones de programas en C qno seria confiables (esto incluye a varios sistemas operativos) ademas esto implica q tampoco confias en las llamadas al kernel de tu SO, si ya no confias en esto pues cambia de SO jejeje! no digo q nunca puedan fallar, pero lo q digo es q si hay memoria disponible "malloc/calloc" te la van a dar y si llamas a "free" la memoria va a ser liberada. "maloc/calloc" pueden llegar a fallar (devolver NULLporque no hay memoria) con una mayor probabilidad que la de que "free" no libere la memoria! La memoria es un recurso escaso e importante y el kernel del sistema maneja muy bien y eficientemenete estas cosas.... o deberia hacerlo porlo menos!

Si aun asi no te convences de que free no libera tu memoria puedes usar el programa "valgrind" (Solo para UNIX) que una pequeña maquina virtual que corre tu programa y lleva la cuenta de todo el manejo de memoria del proceso y mas, es una herramiente muy potente en UNIX para el manejo de "memory leaks" y errores de lectura y escritura en posiciones de memoria inadecuada q causan esos malditos "Segmentation Fault" (quien no ha visto uno de sos en C jajajajaja)
si te lo bajas lo puedes corre asi:
"valgrind ./mi_prg"

tiene muchas opciones algunas piolas son:
"valgrind --leak-check=full ./mi_prg"  --> Sigue el rastro detodoslos punteros y te dice cuanta y donde esta la memoria que aun no has liberado!

"valgrind -v ./mi_prg"  -->  Lo hace mas "verborragico" y hace quete tire mas detalles... lo corresy los ves! y haceslasprubas y veras q "free" simpre libera!



Citar
A lo mejor estoy en una ignorancia enorme, pero jamas he visto en ningun libro de C o C++ que se diga que despues de liberar memoria con free hay que asignarle NULL o cero a un puntero... Jamas he visto eso. Y si esto es asi, entonces la funcion free no es efectiva y no hace su trabajo que se supone que ha de hacer... o lo hace a otro nivel que desconozco ya sea a nivel mas profundo o de hardware que no puedo comprobar su efectividad con simples funciones tipo printf...
Nuncavas a ver en un libro de Calgo asi, ni lo de inicializar variables ni sobre "coding style" ni nada q sean cosas del programador y no del lenguaje! esto es recomendabla solo porque los programadores tiene un 99% de probabilidad de cometer errores! hasta el mas groso de los grosos comete errores en programas grandes! con la practica esto se minimiza pero es inevitable, somo humanos, nos vamos a equivocar y mas vale estar prevenidos!
Y te vuelvo a repetir "free" hace lo q debe hacer Y NADA MAS, solo libera la memoria, no hace otra cosa, elresto core porcuenta delprogramador, esto esasi para darle al programador la mayopr flixibilidad posible de q "haga lo q quiera", lasfunciones de C hacen lo minimoe indispensable y nada mas! por ellos suelen hacer bien o q hacen!!




Citar
Incluse fui mas lejos, intente asignarle cero con malloc a mi puntero :

if ((puntero = malloc(0)) == 0) {
printf("No se reservo");
} else {
print("Se reservo");
}

Y adivinen cual secuencia me responde? La segunda... "Se reservo". Sin embargo si asigno directamente cero a la variable puntero y lo igualo a cero ahi se cumple la primera :

if ((puntero = 0)== 0) {
printf("No se reservo");
} else {
print("Se reservo");
}

Aqui es efectiva la primera seleccion "No se reservo"...

Que pasa aqui... en el primer ejemplo me juego la vida que no has inizializado la variable "puntero" a NULL cuando la declaraste (en caso de q si sorry), ya que un "p=malloc(0)" es equivalente a un "free(p)", esto implica q el valor de tu puntero no se modifica (o si?), ademas malloc devuelve NULL solo cuando NO HAY MEMORIA no cuando le pides 0 bytes! (asta donde se yo, esto es asi, me corrijan si estoy mal).
Y con respecto al segundo ejemplito digo... es muy obvio jaja "if ((puntero = 0)== 0)" va a dar simpre vardadero, no hay nada de magia de punteros ahi.

Otra cosa... los punteros deberias comparalos y asignarlos a NULL y no a 0 ya q almacenan direcciones de memoria y no enteros, digo.... ya se que "NULL == (void *)0" pero para algo esa no?
Repito esto no esta en libros, son cosas de los programadores por el echo de q nos vivimos equivocando todo le tiempo!


Espero haberte ayudado aunquesea un poquito... o a confundirte mas por lo menos jajajajajaja!!!

Salu2!
En línea
dooque

Desconectado Desconectado

Mensajes: 149



Ver Perfil
Re: Comprobar si libere o no memoria dinamica..
« Respuesta #12 en: 12 Noviembre 2008, 14:54 »

sorry! mientras escribia pusieron dos pos mas y se repite un poco lo q digo.. jejeje! para q veas q la mayoria piensa igual! jaja!! saludos!
En línea
EvilGoblin


Desconectado Desconectado

Mensajes: 2.320


YO NO LA VOTE!


Ver Perfil
Re: Comprobar si libere o no memoria dinamica..
« Respuesta #13 en: 12 Noviembre 2008, 15:19 »

Código:
strlen(puntero);
?

Mayormente yo limpio el buffer y para saber si esta limpio y liberado hago un Strlen(puntero)


Suerte
En línea

Experimental Serial Lain [Linux User]
^Tifa^


Desconectado Desconectado

Mensajes: 2.802


Ver Perfil
Re: Comprobar si libere o no memoria dinamica..
« Respuesta #14 en: 12 Noviembre 2008, 15:33 »

En resumen...

Lo que ando solicitando es demasiado profundo que la unica respuesta que obtengo es 'debes confiar en que eso funciona asi'.

Vaya, que motivador.

No creo que si voy a reservar memoria dinamica en una variable deba inicializarla.. eso es absurdo, sobretodo si se supone que en esta se reservara memoria dinamica, por ende no puedo asignarle de antemano un valor sea cero o sea NULL.

Algo como lo que dice EvolGoblin es lo que busco... pero para liberacion de memoria dinamica :P
En línea
Páginas: [1] 2 Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
¿Como comprobar memoria de mi tarjeta gráfica?[SOLUCIONADO]
Hardware
motocros_elche 4 1,272 Último mensaje 13 Julio 2011, 19:52
por motocros_elche
Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines