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

Problema con memoria dinamica en listas enlazadas

Estas en el tema de Problema con memoria dinamica en listas enlazadas en el foro de C/C++ en Foros del Web. Hola maestros, tengo un pequeño problema al momento de agregar elementos a mi lista enlazada pues me tira errores de memoria, yo recervo la memoria ...
  #1 (permalink)  
Antiguo 11/09/2006, 15:05
Avatar de El_Metallick  
Fecha de Ingreso: noviembre-2002
Ubicación: Santiago, Chile
Mensajes: 1.718
Antigüedad: 21 años, 5 meses
Puntos: 16
Problema con memoria dinamica en listas enlazadas

Hola maestros, tengo un pequeño problema al momento de agregar elementos a mi lista enlazada pues me tira errores de memoria, yo recervo la memoria para la estructura pero creo que el problema esta en que dentro de ella tengo strings de largo variable y por ende la memoria que se pide no es suficiente pero la verdad de las cosas es que no se con certesa cual es el problema, les dejo parte de mi código para ver si me pueden ayudar a solucionarlo...

Código:
//Se define la estructura Auto
typedef struct Auto {
       int codigo;        //Código del auto
       char *marca;       //Marca del auto
       char *modelo;      //Modelo del auto
       char *color;       //Color del auto
       char patente[6];   //Patente del auto
       int anho;          //Año del auto
       int n_ejem_disp;   //Número de ejemplares disponibles para el arriendo
       int n_ejemplares;  //Número de ejemplares del auto
       struct Auto *next;
}Auto;

struct Auto *NuevoAuto;
struct Auto *PrimerAuto;
struct Auto *RecorreAuto;
struct Auto *AnteriorAuto;

void Agregar(char *tipo)
{
    char mar[0];
    char mod[0];
    char col[0];
    char pat[6];
    int cod;
    int an;
    int n_ejem;
   
    if (strcmp(tipo,"Auto") == 0)
    {   
         printf("\nEscriba la marca del Auto: ");
         scanf(" %[^\n]", mar);
         printf("\nEscriba el modelo del Auto: ");
         scanf(" %[^\n]", mod);
         printf("\nEscriba el color del Auto: ");
         scanf(" %[^\n]", col);
         printf("\nEscriba la patente del Auto (en formato XX-XXXX): ");
         scanf(" %[^\n]", pat);
         printf("\nEscriba el a%co del Auto: ", 164);
         scanf("%d", &an);
         printf("\nEscriba el n%cmero de ejemplares del Auto: ", 163);
         scanf("%d", &n_ejem);
         
         NuevoAuto = (Auto *)malloc(sizeof(Auto));
         NuevoAuto->marca = (char *)malloc(sizeof(char)*strlen(mar));
         NuevoAuto->modelo = (char *)malloc(sizeof(char)*strlen(mod));
         NuevoAuto->color = (char *)malloc(sizeof(char)*strlen(col));
         NuevoAuto->codigo = CrearCodigo();
         strcpy(NuevoAuto->marca,mar);
         strcpy(NuevoAuto->modelo,mod);
         strcpy(NuevoAuto->color,col);
         strcpy(NuevoAuto->patente,pat);
         NuevoAuto->anho = an;
         NuevoAuto->n_ejem_disp = n_ejem;
         NuevoAuto->n_ejemplares = n_ejem;
         NuevoAuto->next = NULL;
    
         if (PrimerAuto == NULL)
        {
          PrimerAuto = NuevoAuto;
          RecorreAuto = NuevoAuto;
        }
        else
        {
            RecorreAuto->next = NuevoAuto;
         }
   
        RecorreAuto = NuevoAuto;
         free(mar);
        free(mod);
        free(col);
        
        printf("\nAuto agregado correctamente.\n\n");
    }
}
Les agradeceria si me pudieran ayudar.... Saludos y gracias de antemano
__________________
Haz la guerra en la cama y el amor donde se te de la gana...
El tiempo es el mejor maestro, lo único malo es que te mata...¡¡Aprovecha tu tiempo!!
  #2 (permalink)  
Antiguo 11/09/2006, 15:14
Avatar de Instru  
Fecha de Ingreso: noviembre-2002
Ubicación: Mexico
Mensajes: 2.751
Antigüedad: 21 años, 5 meses
Puntos: 52
Bueno, efectivamente tienes algunos errores. No he revisado el codigo entero, pero aun asi te doy algunas de las correcciones que vi.

char mar[0];
char mod[0];
char col[0];



printf("\nEscriba la marca del Auto: ");
scanf(" %[^\n]", mar);
printf("\nEscriba el modelo del Auto: ");
scanf(" %[^\n]", mod);
printf("\nEscriba el color del Auto: ");
scanf(" %[^\n]", col);

No se que intenteabas hacer con esto.

char mar[0];

es equivalente a

char *mar;
mar=(char *)malloc(sizeof(char));

Osea solo tienes un byte disponible.

intenta usar un tamaño estatico temporal, y para ahorrar mas memoria, hazlo con funciones, asi al acabar la funcion, la memoria usada se libera automaticamente.

char mar[256];
Con eso te debe alcanzar.

Espero que estas correciones te resuelvan el problema de la memoria.

Saludos
  #3 (permalink)  
Antiguo 11/09/2006, 16:17
Avatar de El_Metallick  
Fecha de Ingreso: noviembre-2002
Ubicación: Santiago, Chile
Mensajes: 1.718
Antigüedad: 21 años, 5 meses
Puntos: 16
con respecto a lo de mar[0]... es porque te entendi mal lo que me respondiste en el otro post :S en realidad tonto lo que hice... voy a probar haciendolo asi... saludos
__________________
Haz la guerra en la cama y el amor donde se te de la gana...
El tiempo es el mejor maestro, lo único malo es que te mata...¡¡Aprovecha tu tiempo!!
  #4 (permalink)  
Antiguo 11/09/2006, 16:45
 
Fecha de Ingreso: abril-2006
Ubicación: Acapulco Gro. México
Mensajes: 483
Antigüedad: 18 años
Puntos: 2
Y por que tanta optimizacion??

si es idisoensable optimizar, podrias implementar tu propia funcion, para leer cadenas.

las funciones de la libreria estandar, reciben un puntero, pero no recervan memoria.

lo que haria esta funcion seria recervar memoria

ejemplo:

char* LeerCad(char* cad)
{
int index = 0;
char cin = getchar();
cad = (char*)malloc(1);
while(cin != '\n')
{
cad[index] = cin;
index++;
cad = (char*)realloc(cad, index+1);
}
cad[index] = '\0';
}

no la he probado, pero supongo que areglando uno que otro detalle puede funcionar.
  #5 (permalink)  
Antiguo 11/09/2006, 17:14
Avatar de El_Metallick  
Fecha de Ingreso: noviembre-2002
Ubicación: Santiago, Chile
Mensajes: 1.718
Antigüedad: 21 años, 5 meses
Puntos: 16
Nivel7 creeme que yo estoy igual de cansado de todo esto que tu e incluso mas :P jajaja, pero bueno la verdad de las cosas es que como dije en el mensaje anterior voy a tratar de dejar funcionando esto como sea y despues afinar detalles si me alcanza el tiempo... la pregunta esta orientada a como pedir correctamente la memoria para la lista porque me da errores... :S... bueno saludos y gracias por tu paciencia y gracias a Instru por su paciencia tambien
__________________
Haz la guerra en la cama y el amor donde se te de la gana...
El tiempo es el mejor maestro, lo único malo es que te mata...¡¡Aprovecha tu tiempo!!
  #6 (permalink)  
Antiguo 11/09/2006, 17:48
 
Fecha de Ingreso: abril-2006
Ubicación: Acapulco Gro. México
Mensajes: 483
Antigüedad: 18 años
Puntos: 2
claro, lo entiendo, y a eso me refiero yo tambien:

lo que tu haces es esto:

declaras un array de caractereres que funcione como un receptor de la cadena de entrada, para que despues recerves memoria exactamente del tamaño, de la cadena leida.

lo malo de esto es que el array receptor tienen que ser de un tamaño relativamente grande, ya que tienen que aceptar cualquier posibilidad en la entrada.

es por eso que Instru te sugirio un tamaño, de 256.

despues ya recervas memoria para las cadenas miembro.

lo que te propuse es evitar esos dos pasos, y lasinar la cadena leida directamente a las cadenas miembro, y ademas la memoria ocupada seria exactamente del tamaño de numero de caracters contenidos.

ejemplo:
//usando la funcion descrita en el mensaje anterior.

en lugar de hacer:

char marc[255];
char mod[255];
scanf("%s\n", marc);
scanf("%s\n", cad);
Auto->marca = (char*)malloc(strlen(marc)+1);
Auto->modelo= (char*)malloc(strlen(mod)+1);
strcpy(Auto->marca, marc);
strcpy(Auto->modelo, mod);

solo harias:

LeerCad(Auto->marca);
LeerCad(Auto->modelo);

con forme se lean caracteres de la entrada las cadenas se iran dimencionando.

ya solo te quedara liberar la memoria.

Bueno, solo es una sugerencia, aqui estamos.
Saludos.
  #7 (permalink)  
Antiguo 11/09/2006, 21:31
Avatar de El_Metallick  
Fecha de Ingreso: noviembre-2002
Ubicación: Santiago, Chile
Mensajes: 1.718
Antigüedad: 21 años, 5 meses
Puntos: 16
mmm, la verdad de las cosas es que no pude hacer funcionar el código que mencionas Nivel7... aunque por ahora ya he solucionado algunos problemas al respecto aun me esta dando fallos cuando intento ingresar arriendo :S la verdad de las cosas es que creo que por hoy ya es mucho... un cafe un cigarro y a la cama para mañana seguir porque ya colapse con todo esto, reitero mis agradecimientos master... Saludos
__________________
Haz la guerra en la cama y el amor donde se te de la gana...
El tiempo es el mejor maestro, lo único malo es que te mata...¡¡Aprovecha tu tiempo!!
  #8 (permalink)  
Antiguo 12/09/2006, 03:42
 
Fecha de Ingreso: abril-2006
Ubicación: Acapulco Gro. México
Mensajes: 483
Antigüedad: 18 años
Puntos: 2
jaja, si en realidad el codigo es totalmente incorrecto, toma en cuenta que solo lo he escrito aqui en el foro, con forme se me ocurre,
es solo la idea, me he pasado de bueno y lo corregi en funcionamiento.

te lo dejo con un pequeño ejemplo:

Código:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char* getstr();

int main()
{
	char* nombre;
	nombre = getstr();
	printf("La cadena: %s, tienen una longitud de: %i\n", nombre, strlen(nombre));
	free(nombre);  //no olvides usar free(), para cada cadena que lees con getstr().
	return 0;
}

char* getstr()
{
    int index = 0;
	char* cad = (char*)malloc(sizeof(char));
	while(true)
	{
		cad[index] = getchar();
		if(cad[index] == '\n'){cad[index] = '\0';return cad;}
		index++;
		cad = (char*)realloc(cad, sizeof(char)*(index +1));
	}
}
espero que esto te facilite el manejo optimizado de cadenas.

Saludos.
  #9 (permalink)  
Antiguo 12/09/2006, 10:47
Avatar de El_Metallick  
Fecha de Ingreso: noviembre-2002
Ubicación: Santiago, Chile
Mensajes: 1.718
Antigüedad: 21 años, 5 meses
Puntos: 16
Muchisimas gracias master Nivel7... reitero mi agradecimiento por tu paciencia y ganas de ayudar... saludos
__________________
Haz la guerra en la cama y el amor donde se te de la gana...
El tiempo es el mejor maestro, lo único malo es que te mata...¡¡Aprovecha tu tiempo!!
  #10 (permalink)  
Antiguo 12/09/2006, 18:02
 
Fecha de Ingreso: abril-2005
Mensajes: 3.083
Antigüedad: 19 años
Puntos: 17
char mar[1];

es equivalente a 1 byte.

char mar[0] es equivalente a 0, es decir, nada. Y no se puede declarar un void en C.

Yo diría que el compilador debería avisar al menos de eso. No sé si el estándar de C define que un array [0] es igual que [1].
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




La zona horaria es GMT -6. Ahora son las 09:46.