/
Inicio :: Foros

 F.A.Q.F.A.Q.                  Conéctese para revisar sus mensajesConéctese para revisar sus mensajes   

Reservar memoria

 
      Índice del Foro elrincondelc.com -> C/C++ en General
Ver tema anterior :: Ver siguiente tema  
AutorMensaje
ALAM



Registrado: 09 Feb 2006
Mensajes: 83

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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

MensajePublicado: 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
      Índice del Foro elrincondelc.com -> C/C++ en General
Página 1 de 1Todas las horas están en GMT - 8 Horas

 
No puede crear mensajes
No puede responder temas
No puede editar sus mensajes
No puede borrar sus mensajes
No puede votar en encuestas

(c) ElRincondelC.com

Un proyecto de UrlanHeat.com