Foros del Web » Programación para mayores de 30 ;) » C/C++ »

[SOLUCIONADO] dudas de memoria dinamica

Estas en el tema de dudas de memoria dinamica en el foro de C/C++ en Foros del Web. hola a todos. bueno tengo unas dudas bueno pues yo no sabia que que realloc se podia usar solo y bueno queria saber si ese ...
  #1 (permalink)  
Antiguo 29/04/2014, 21:36
Avatar de Drewermerc  
Fecha de Ingreso: febrero-2014
Mensajes: 185
Antigüedad: 10 años, 2 meses
Puntos: 5
dudas de memoria dinamica

hola a todos.

bueno tengo unas dudas bueno pues yo no sabia que que realloc se podia usar solo y bueno queria saber si ese metodo es igual de efectivo que usar malloc y realloc juntos.

y tambien queria saber por que si guardo datos usando scanf al imprimir los valores me resultados erroneos asi.(aclaro esto es solo cuando se usa realloc solo.)

Código C:
Ver original
  1. Lista enlazada
  2.     Elemento 1 de la lista enlazada (0 para salir): 5
  3.     Elemento 2 de la lista enlazada (0 para salir): 5
  4.     Elemento 3 de la lista enlazada (0 para salir): 5
  5.     Elemento 4 de la lista enlazada (0 para salir): 5
  6.     Elemento 5 de la lista enlazada (0 para salir): 0
  7.     0 0 0 135153

veo que la malloria usa

Código C:
Ver original
  1. //aceder a los datos
  2.     *(lista+i-1) = 5;
  3. //guardar datos con scanf
  4.     &*(lista)

este tipo para acceder a datos de la memoria o guardar datos en ella yo por regular uso mas este metodo.

Código C:
Ver original
  1. lista[i+1];
  2.     &lista[i];

que funciona igual nose si algun metodo es es el correcto o los dos son corecto y es como cadaquien se acomode a programar.
tambien queria saber cual es la diferencia entre esto:

Código C:
Ver original
  1. //si en un programa pongo esto da error al llegar a los 6 registros
  2. realloc(lista,i+1*sizeof(int));
  3. //pero si lo pongo asi ya no tengo el error
  4. realloc(lista,(i+1)*sizeof(int));
  5.  
  6. //codigo completo
  7.  
  8.     #include <stdio.h>
  9.     #include <stdlib.h>
  10.      
  11.     main()
  12.     {
  13.     int *lista,i=0,r;
  14.     puts("Lista enlazada");
  15.      
  16.     lista=(int *) malloc(sizeof(int));
  17.      
  18.     printf("\nElemento %d de la lista enlazada y preciona 1 para agrgar otro elmento",i+1);
  19.     scanf("%d",&*(lista));
  20.             scanf("%d",&r);
  21.                 while(r==1)
  22.                 {
  23.                     i++;
  24.                     realloc(lista,i+1*sizeof(int));
  25.                     scanf("%d",&*(lista+i));
  26.                     puts("Desea agregar otro elemento");
  27.                     scanf("%d",&r);
  28.                    
  29.                 }
  30.        
  31.         for(int x=0;x<i+1;x++)
  32.         {
  33.         printf("%d ",lista[x]);
  34.        
  35.         }
  36.        
  37.         free(lista);
  38.     }
la verdad yo pense que la memoria dinamica no tenia mcuho uso pero ahora veo que te ayuda a manejar mucho mejor la memoria.
con lo que me surge otra duda si se puede trabar la memoria dinamica y manejar como matrizes, arrays unidimencionales etc. entonces cual seriamas conveniente usar memoria dinamica o las otras opciones o depende del programa que se desallorre.
bueno espero que me puedan ayudar.
saludos a todo.
  #2 (permalink)  
Antiguo 07/05/2014, 12:37
 
Fecha de Ingreso: agosto-2012
Mensajes: 601
Antigüedad: 11 años, 8 meses
Puntos: 83
Respuesta: dudas de memoria dinamica

Ejecuta tu codigo en el depurador, y veras que hay cosas que no funcionan.

Ya se que no debo hacerlo, pero te cuelgo un codigo completo de tal como resolveria la lista (no es la unica forma ni la mas eficiente, pero puedes sacar ideas); debajo te comento un par de cosas (de todas formas he comentado las lineas mas interesantes del codigo):

Código C:
Ver original
  1. #include <stdio.h>
  2.  
  3. void fflush_stdin() {
  4.     char c;
  5.     while((c = getchar()) != EOF && c != '\n');
  6. }
  7.  
  8.  
  9. int main() {
  10.     int *lista, *temporal, contador, input, q;
  11.     size_t szmem;
  12.  
  13.     lista = 0;
  14.     contador = 0;
  15.  
  16.     //bucle infinito
  17.     while(1) {
  18.         //añadir elemento
  19.         printf("Quieres añadir un elemento? (s/n)");
  20.         if(getchar() != 's') {
  21.             break;
  22.         }
  23.        
  24.         //recupera input de usuario
  25.         printf("Dime el valor para la posicion %d:" , contador);
  26.         scanf("%d", &input);
  27.         fflush_stdin();
  28.        
  29.         //determina nueva posicion y tamaño de la lista
  30.         contador++;
  31.         szmem = sizeof(int) * contador;
  32.  
  33.         //reserva memoria
  34.         if(!lista) {
  35.             //nueva lista
  36.             if(!(lista = malloc(szmem))) {
  37.                 //memoria insuficiente
  38.                 break;
  39.             }
  40.         }
  41.         else {
  42.             //expande lista existente
  43.             if(!(temporal = realloc(lista, szmem))) {
  44.                 //memoria insuficiente
  45.                 break;
  46.             }
  47.             //restablece lista
  48.             lista = temporal;
  49.         }
  50.        
  51.         //asigna valor
  52.         *(lista + contador - 1) = input;
  53.        
  54.         //valor insertado
  55.         //printf("%d=>%d\n", contador, *(lista + contador - 1));
  56.     }
  57.  
  58.     //final
  59.     if(lista) {
  60.         //volcar lista
  61.         for(q = 0; q < contador; q++) {
  62.             printf("%d=>%d\n", q, *(lista + q));
  63.         }
  64.        
  65.         //libera memoria
  66.         free(lista);
  67.     }
  68.  
  69.     return 0;
  70. }

Observa la linea del realloc: esta funcion en caso de exito retorna la nueva posicion del bloque de memoria, y retorna nulo en caso de error. Eso significa que en caso de exito la linea que tienes en tu codigo provocará una violacion de segmento en el siguiente acceso a la lista:

Código C:
Ver original
  1. //esto es parte de tu codigo, linea 24
  2. realloc(lista,i+1*sizeof(int));

En caso de exito el bloque previo de lista será movido a otra posicion para albergar la nueva memoria solicitada, es decir que la posicion previa de lista ya no está disponible, y los siguientes intentos de acceso a 'lista' provocan el segfault. Se soluciona tal como te dejo en el ejemplo: asignar el retorno a una variable temporal sobre la que vas a hacer las comprovaciones. Si asignas el retorno de realoc a la misma variable, en caso de error no podras recuperar el bloque previo y provocaras una perdida de memoria, por eso se usa una variable temporal intermediaria.

De forma parecida tienes que escanear el nuevo valor en una variable auxiliar, en vez de directamente en la posicion de memoria. De esta forma puedes hacer comprovaciones y decidir si ese valor es valido para la lista.

Revisa este ejemplo y compara con el codigo que colgaste, si hay algo (una duda o un error por mi parte) ya sabes que puedes comentarlo aqui mismo ;)

Espero que te sea de ayuda.

Saludos
vosk


p.s. una ultima observacion:

Código C:
Ver original
  1. //parte de tu codigo, linea 18
  2. printf("\nElemento %d de la lista enlazada y preciona...

'preciona' va con 's' :), saludos
  #3 (permalink)  
Antiguo 07/05/2014, 22:19
Principe_Azul
Invitado
 
Mensajes: n/a
Puntos:
Respuesta: dudas de memoria dinamica

Cita:
En caso de exito el bloque previo de lista será movido a otra posicion para albergar la nueva memoria solicitada, es decir que la posicion previa de lista ya no está disponible, y los siguientes intentos de acceso a 'lista' provocan el segfault. Se soluciona tal como te dejo en el ejemplo: asignar el retorno a una variable temporal sobre la que vas a hacer las comprovaciones. Si asignas el retorno de realoc a la misma variable, en caso de error no podras recuperar el bloque previo y provocaras una perdida de memoria, por eso se usa una variable temporal intermediaria.
comprobaciones



Excelente explicación vosk, muy buenos y entendibles tus códigos, gracias!!
  #4 (permalink)  
Antiguo 08/05/2014, 21:48
Avatar de Drewermerc  
Fecha de Ingreso: febrero-2014
Mensajes: 185
Antigüedad: 10 años, 2 meses
Puntos: 5
Respuesta: dudas de memoria dinamica

hola vosk.
gracias por responder.
revisare bien tu codigo ya voy entendiendo mas el uso de memoria dinamica, bueno gracias de nuevo.
saludos.
drewermerc.

Etiquetas: dinamica, dudas, funcion, int, memoria, programa, usar
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 1 personas




La zona horaria es GMT -6. Ahora son las 06:49.