[C con Clase] Pila dinámica: guardar datos.

Steven Davidson srd4121 en njit.edu
Vie Feb 26 04:23:28 CET 2010


Hola Gustavo,

Gustavo Adolfo Torres Ortega wrote:
> Hola, que tal.
> 
> Estoy estudiando sobre estructuras de datos, y me pidieron que
> guardara datos en una pila dinámica.
> El problema es que no sé si estoy declarando funciones y valores como
> debería, ya que cuando compilo mi programa con NetBeans, me aparece
> un error que dice lo siguiente:
> 
> Error while dumping state (Probably corrupted stack).
> 
> ¿En qué está mal mi código?
> 

Veamos el código fuente.

> 
> #include <stdio.h>
> #include <stdlib.h>
> 
> struct Pila
> {
>   char dato;
>   struct Pila *base;
> };
> 
> typedef struct Pila Pila;
> 
> int push(Pila *a, char d);
> char pop (Pila *a);
> int empty(Pila *a);

Deberías aceptar un puntero a 'const Pila'. Al fin y al cabo, esta 
función no pretende modificar la pila.

> 
> int main()
> {
>   Pila *a;
>   a=NULL;
>   char d='a';
>   if(push(&a,d))                   //Por el momento solo guardo un solo 
> valor.

Aquí tienes dos errores. El primero es que el tipo del primer parámetro 
no coincide con el del prototipo de 'push()'. Estás pasando un doble 
puntero, pero 'push()' sólo acepta un puntero "singular". Modifica 
'push()' para aceptar un doble puntero.

Ten presente que 'a' no es más que un puntero y previamente le has 
asignado 'NULL'. Al invocar 'push()', la función intenta acceder al 
miembro 'base', pero esto no es posible ya que no existe ninguna 
información de tipo 'Pila'.

Deberías crear memoria dinámicamente para 'a' antes de invocar 'push()'. 
La otra solución es rediseñar 'push()' para que tenga este detalle en 
cuenta - cuando la pila esté vacía.

>     printf("\nValor guardado: %c",a->dato);
>   else
>     printf("\nValor no guardado\n");
>   printf("\n\n\t");
>   return 0;
> }
> 
> int push(Pila *a, char d)
> {
>   Pila *aux;
>   aux=(Pila*)malloc(sizeof(Pila));
>   if(aux!=NULL)
>   {
>     aux->dato=d;
>     aux->base=a;
>     a->base=aux;

Esto será un problema si 'a' no apunta a memoria previamente reservada 
(creada). Sugiero determinar si 'a' está vacía o no antes de acceder a 
los miembros apuntados por 'a'. Por ejemplo,

if( empty(a) )
{
   // liga este registro correctamente
}

Claro está, si 'a' está vacía, entonces 'push()' debe modificar el 
puntero original. Esto implica que deberías aceptar un doble puntero, 
como mencioné anteriormente.

>     return 1;
>   }
>   return 0;
> }
> 
> char pop (Pila *a)
> {
>   char d=a->dato;
>   Pila *aux;
>   aux=(Pila*)malloc(sizeof(Pila));

Cuando estamos eliminando algo, es muy sospechoso que tengamos que crear 
memoria para poder eliminar ese algo. Lo que tienes que hacer es religar 
los "eslabones".

>   aux=a->base;
>   free(a);
>   a->base=aux;
>   return d;
> }

Nuevamente, puede darse el caso de que se elimine el último registro. 
Esto significa que tendremos que modificar el puntero original para que 
sea nulo en el caso de que la pila se vacíe.

Esto implica que tendrás que modificar el prototipo de 'pop()' para que 
acepte un doble puntero.

> 
> int empty(Pila *a)
> {
>   if(a==NULL)
>     return 1;
>   return 0;

Podemos reescribir esto de otra manera para no tener que comprobar una 
condición, ya que no nos interesa comprobar nada. Esto es,

return a == NULL;

> }
> 


Espero que esto te ayude.

Steven





Más información sobre la lista de distribución Cconclase