| Ver tema anterior :: Ver siguiente tema | | Autor | Mensaje |
|---|
ALAM
Registrado: 09 Feb 2006 Mensajes: 83
| Publicado: 14/03/2007 5:18 am | | | Título: Reservar memoria |
| Hola, después de haber dejado el tema por un tiempo, estoy retomandolo y me asalta una duda que seguro es una tontería pero quiero aclarame.
Cuando reservo memoria para un puntero a través de malloc o calloc y la libero con free, o en c++ la reservo con new y libero con delete, la pregunta es: Es necesario reservar la memoria cada vez que quiera hacer uso del puntero, evidentemente después de liberar, o simplemente , después de liberarla lo reutilizo y ya, sin volver reservar memoria?
Gracias |
| | Volver arriba | |  | rir3760

Registrado: 01 Oct 2004 Mensajes: 4818 Ubicación: Mexico
| Publicado: 14/03/2007 6:12 am | | | Título: |
| Una vez que llamas a free (o delete) el bloque de memoria se libera y el entorno puede utilizarlo para lo que sea. En este punto el puntero que tenias ya no es valido y si tratas de utilizarlo se produce undefined behaviour. En otras palabras puede pasar lo que sea, usualmente es el mensaje de "SEG FAULT ... " o "Invalid Page Fault ...".
Un saludo _________________ The capacity to learn is a gift; The ability to learn is a skill; The willingness to learn is a choice. -- Rebec of Ginaz |
| | Volver arriba | |  | ALAM
Registrado: 09 Feb 2006 Mensajes: 83
| Publicado: 15/03/2007 1:09 am | | | Título: |
| A ver si me puedo aclarar.
| Código: | double *pPuntero; if ((pPuntero = (double *)calloc( 30, sizeof (double))) == 0) return FALSE;
for (in i = ........) { for (int j = .........) pPuntero [j] = ..........; nueva_variable = multiplica_array(array1, pPuntero); free (pPuntero); } |
En el ejemplo anterior he reservado memoria para un puntero, el cual utilizaré dentro de los bucles for. En el bucle más interior realizo alguna operación que guardará ciertos valores en un array apuntado por pPuntero, al finalizar ese bucle, salgo de él, y llamo una una función llamada multiplica_array que hace uso del puntero, pero al iniciar la siguiente iteración del bucle for más exterior tengo que liberar el puntero, para eso utilizo free antes de iniciar la nueva iteración. Vale. El caso es: para esta nueva iteración debo reservar memoria nuevamente o simplemente al haberle reservado inicialmente y solo liberandola, cada vez para cada iteración, basta. |
| | Volver arriba | |  | | rir3760

Registrado: 01 Oct 2004 Mensajes: 4818 Ubicación: Mexico
| Publicado: 15/03/2007 5:31 am | | | Título: |
| Si el lenguaje que estas estudiando es C++ deberias utilizar el par new + delete.
Por otra parte si el lenguaje es C no es necesario realizar la conversion explicita o casting, basta con:
| Código: | tipo_X *p;
/* ... */
p = malloc(N * sizeof *p);
if (p == NULL){
/* manejo de error */ }
/* ... */ |
Donde N es el numero de elementos. De esta forma si despues cambias el tipo de p de "tipo_X *" a "tipo_Y *" esa linea no requiere cambio alguno.
El fragmento de tu programa no es correcto por lo siguiente:
1) Reservas la memoria mediante malloc. OK.
2) Entras en un bucle donde utilizas ese bloque. Solo en la primera iteracion el puntero apunta a un bloque valido. OK.
3) Liberas el bloque de memoria, en ese momento el bloque al cual apunta el puntero puede utilizarse por el entorno para lo que sea y ya no es valido. La unica solucion en este momento es volver a pedir otro bloque de memoria al entorno mediante una llamada a malloc/calloc/realloc.
4) El bucle se repite de nuevo pero a partir de la segunda iteracion, como el puntero ya no es valido al tratar de reutilizarlo cualquier cosa puede pasar (undefined behaviour).
Si estamos hablando de C ese bloque tendria que ser (mas o menos) asi:
| Código: | double *p;
for (...){ if ((p = malloc(30 * sizeof *p)) == NULL) return FALSE; /* ** Utilizar calloc para asignar el valor 0.0 a todos los ** elementos del bloque no es 100% seguro. En su lugar es ** mejor asignar mediante un bucle. */ for (i = 0; i < 30; i++) p[i] = 0.0; for (...) p[j] = ...; nueva_variable = multiplica_array(array1, pPuntero); free (p); } |
Si bien el codigo es correcto no es eficiente ya que el bloque de memoria se reserva, inicializa y libera en cada iteracion del bucle.
Un saludo _________________ The capacity to learn is a gift; The ability to learn is a skill; The willingness to learn is a choice. -- Rebec of Ginaz |
| | Volver arriba | |  | ALAM
Registrado: 09 Feb 2006 Mensajes: 83
| Publicado: 15/03/2007 8:39 am | | | Título: |
| vale, la cosa va mejor.
Otras dudas me asaltan. Es importante (lo más correcto) liberar el bloque de memoria cuando ya no la necesitas. En el caso de una función que retorna un puntero, qué ocurre con el puntero retornado. Me explico, cuando termina la función, el return es el puntero, e inmediatamente salgo de la función: ¿cuándo libero esa memoria? ¿la memoria se libera al destruirse la variable que la apunta debido a que se ha cerrado su ámbito de existencia? Cuando una función retorna un puntero, el que recibe el resultado de dicha función (supongamos) es otro puntero, que apunta al mismo tipo de datos: ¿A este puntero (el receptor), se le debe haber reservado memoria? o por el hecho apuntar a un espacio de memoria reservado (aunque apuntado por otro puntero, en principio) no requiere de esto. Gracias |
| | Volver arriba | |  | | |
| No puede crear mensajes No puede responder temas No puede editar sus mensajes No puede borrar sus mensajes No puede votar en encuestas
|
|
| |