¿Como duplico los nodos de una pila si no se cuanto espacio debo reservar para los nuevos nodos?
Lo ideal seria realizar una duplicacion nodo a nodo verificando el tipo de dato contenido,
sin embargo si el dato almacenado es otro puntero (como en elcaso de las cadenas) tal vez seria de gran ayuda (sino necesario) tener otro campo en la estructura que indique el tamaño del tipo de dato almacenado en el caso de que sea un puntero.
¿Puedo usar un malloc con el tipo de datos void?.
No lo recuerdo pero supongo que si.
a la misma zona de memoria!!! los datos son los mismos!.
umm si asi es, pero si llo vemos desde el punto de vista funcional puede que no siempre esas sean las intenciones del desarrolador...
adivina...
requeririamos otro campo que nos indique si el puntero posee su propio espacio en memoria o si apunta a un segmento 'compartido' por decirlo de algun modo, esto con el fin de que en el momento de liminar un nodo se verifique que tipo de puntero es, y si es compartido se borra la referencia pero no el contenido en memoria y si es propio se borarian tanto la referencia como el contenido.
- El problema anterior tambien me ha surgido al intentar implementar la funcion de concatenar pilas. Dado que aunque concatene pilas, la pila resultante tendra nuevos nodos, vale, pero sin embargo dichos nodos tendran apuntadores a los datos que tambien estan siendo apuntados por las pilas que han sido concatenadas.
Se solucionaria con el comentario anterior.
Estoy pensando en mantener una lista enlazada que crezca por cada pila que se solicite y que contenga un identificador entero para identificar la pila dentro de la lista.
Esto es lo mejor, pero adicionalmente podrias poner un limite a la creacion de pilas y decir por ejemplo que puedes manejar 255 pilas seria una buena idea.
Ahora pasando al tema de la programacion tengo nuevas observaciones.
1-no deberias usar usar exit(1) ni ninguna de sus variantes realmente esta instruccion invoca una de las interrupciones del DOS y se usaba para recuperar el contexto de ejecucion del sistema operativo una ves ejecutado un programa, pero esta fucion contribuye a una mala estructura en el codigo ya que causa una salida abrupta del programa y no deja que este continue su ciclo normal.
en su lugar deberias hacer algo como esto:
int creaPila(char *error)
{
struct nodo **aux;
int i;
int ret;
char err[255];
memset(err,'\0',255);
if((aux = (struct nodo **) malloc(sizeof(struct nodo *)*num_pilas)) == NULL)
{
strcpy(err,"Error al crear la pila");
ret = NULL;
}
else
{
for(i = 0; i < num_pilas; i++)
aux[i] = pilas[i];
if((pilas = (struct nodo **) malloc(sizeof(struct nodo *)*(num_pilas + 1))) == NULL)
{
ret = NULL;
strcpy(err,"Error al crear la pila");
}
else
{
num_pilas++;
for(i = 0; i < num_pilas - 1; i++)
pilas[i] = aux[i];
pilas[num_pilas-1] = NULL;
ret = num_pilas-1
}
}
error=err;
return ret;
}
Bueno eso es una idea muy basica puedes mejorarla un poco más.
2- En tu libreria no deberian haber perror (por eso los quite arriba) y de hecho nada que imprima ni que termine el programa (como el exit), todo deberia estar tan controlado y manejado que el usuario podria validar que si por ejemplo CrearPila fallo el se entere revisando que devolvio null y si quiere detalles del error revisaria el contenido de la cadena error, y seria el usuario (osea el desarrolador que use tu libreria) quien decida si termina el programa o si libera recursos para que haya mas memoria o si trata de hacer cualquier cosa que el quiera. La libreria no puede decidir por el usuario.
Por eso en el primer post te sugeria que existiera una fucion que devolviera un string con el contenido del nodo incluso variantes que solo devuelvan el dato y ortras que devuelvan la info completa pero nunca que lo impriman directamente.