Título: Puntero doble Publicado por: LadyWin en 15 Agosto 2021, 06:30 am Buenas noches! como andan? queria consultarles algo que me tiene un poco confundida...
Código
Como 'COLA' es un puntero entonces 'ppio' seria un doble puntero? si no es asi, como seria su correcta definicion? Utilizo este modo ya que necesito pasar parametros por referencia para que sus datos se modifiquen en los modulos, pero termina siendo medio engorroso a la hora de acceder a sus campos, siempre me salen muchos errores,por ejemplo este me salio sin ningun problema: Código
Pero en este no, me salen un monton de errores siendo que los hice de la misma manera: Código
Si me pueden ayudar seria de gran ayuda, desde ya muchas gracias! ;-) Título: Re: Puntero doble Publicado por: MAFUS en 15 Agosto 2021, 16:06 pm Bueno, la verdad es que es te estás liando un poco con los punteros y los dobles punteros.
Código: (*aux)->sgte = nuevoNodo; Aquí nuevoNodo es COLA * nuevoNodo, lo que es lo mismo, struct tCola ** nuevoNodo (un puntero doble). Pero sgte espera un puntero simple: Código: typedef struct tCola { En la definición se puede ver que sgte es un puntero simple. Ídem para Código: aux = (*aux)->sgte; Título: Re: Puntero doble Publicado por: RayR en 15 Agosto 2021, 18:46 pm Aquí también tienes un error:
Código: (*nuevo_elemento)->contenido.DNI = nuevoDato->DNI; porque reservaste memoria para nuevo_elemento, pero no para *nuevo_elemento, por lo que este último es un puntero sin inicializar, así que en la línea anterior estás escribiendo en quién sabe que dirección. Antes tienes que hacer algo como esto: Código: *nuevo_elemento = (COLA)malloc(sizeof(tCola)); De todas formas, piensa bien si de verdad necesitas tantas indirecciones. Puedes pasar variables por puntero/referencia sin usar realmente un puntero, simplemente usando el operador &. Fíjate a ver si puedes simplificar tu programa. Título: Re: Puntero doble Publicado por: LadyWin en 15 Agosto 2021, 20:30 pm Gracias por responder! Entiendo lo que me dicen, pero entonces no es posible acceder a los campos cuando la sintaxis es hecha de este modo?, aca hice un codigo mas simple, 'ppio' ya no es puntero pero tambien me sale el mismo error:
Código
Lo que quiero evitar es escribir (**) por esta razon quiero buscar otras alternativas, desde ya muchas gracias! ;D Título: Re: Puntero doble Publicado por: RayR en 16 Agosto 2021, 03:34 am Si tienes algún manual de C, revisa bien la sección de punteros, porque sigues confundiendo mucho las cosas. A lo que me refiero con mi mensaje anterior es a que cuando tienes una variable ptr que es un puntero a puntero (o puntero doble como dices), debes inicializar tanto a ptr como a *ptr. Para este ejemplo, eso significa que necesitas dos llamadas a malloc, cada una reservando el espacio necesario y haciendo el cast al tipo correspondiente para cada puntero. No estás haciendo ninguna de esas cosas en la línea 25, y además, dado que nuevo es un puntero a puntero, lo estás desreferenciado mal ( (*nuevo)->campo es la manera correcta). De cualquier forma te estás complicando más de lo necesario, ya que nuevo no necesita ser un puntero a tNodo. Simplemente cambia la línea 25 a:
Código: tNodo nuevo = (tNodo)malloc(sizeof(struct rNodo)); y la 28 a Código: *ppio = nuevo; Título: Re: Puntero doble Publicado por: MAFUS en 16 Agosto 2021, 10:45 am Mejor sería reestructurar los tipos de datos: uno para tener guardar el dato mismo y otro para guardar la cola.
Verás que no se han hecho uso de punteros dobles. Muchas veces se pueden evitar Dato: Código
El dato guarda la información útil más un puntero que hace la lista. En verdad se podría realizar una estructura anidada, la estructura interna con el dato y la externa que contendrá el puntero (pero eso ya más avanzado). Cola: Código
La cola nos sirve para trabajar con la estructura cola, nada más. Guarda el primer dato, el último y el número de elementos. Teniendo ya los dos tipos de datos estructurados vamos a crear la funcionalidad para manejarlos de forma sencilla. A por las funciones: Para los datos ....... Primero vamos crear el dato Código
Esto genera un tipo dato en memoria dinámica, nada del otro mundo. Lo único que hay que tener en cuenta es que los campos que se deben alojar en memoria dinámica, como nombre, debe hacerse mediante el uso de *alloc. Esto es especialmente así sobre todo en cadenas que te pueden venir de diferentes formas y no se puede asignar directamente el valor de la variable nombre a dato->nombre por la razón de que te pueden pasar un puntero de un array local y al salir de la función esa memoria sería liberada, es decir, si te hacen esto: Código: DATO dato_crear(int dni, char *nombre) { Repito, lo anterior está mal. Por otra parte se ve que 'siguiente' va a NULL, esto es así para que se puedan encontrar fallos de lógica. Liberar dato de la memoria Código
Antes de liberar el dato propiamente dicho hay que liberar la memoria que ha adquirido para su funcionamiento, en este caso la cadena nombre. Como puedes haber observado este es el funcionamiento básico, no hay guardas para saber si no se han pasado datos NULL o que no hayan ocurrido errores, pero esto es a lo que vamos. Vamos a por la cola..... Primero se crea la cola Código
Sencillo se genera en memoria dinámica y se ponen todos los elementos a 0 o NULL. Agregar un dato a la cola Código
Los datos a una cola se introducen por el final, nuestro dato COLA ya tiene un puntero a su último elemento así que el trabajo es sencillo. Lo único que hay que tener en cuenta es si la cola está vacía: si está vacía el elemento introducido no sólo es el último sino que también es el primero; si la cola no está vacía hay que tener presente para el buen funcionamiento de nuestra estructura de datos que el último elemento de la cola apunte al que vamos a agregar. Extraer un dato de la cola Código
Como en una pila los datos se extraen desde e principio. Es importante saber dos cosas: si al principio la cola está vacía por lo que se tendrá que devolver NULL y no hacer nada más; que después de la extracción la cola se vacíe (donde cola->primero tendrá el valor NULL) en ese caso y para evitar problemas lógicos también se lleva a NULL cola->ultimo. Desalojar la cola de memoria Código
Como con dato primero hay que liberar toda la memoria que haya alojado. Esto se hace recorriendo la lista con cola->primero hasta que sea NULL. Ver que se usa la funcion dato_liberar porque cada dato se debe desalojar usando su propia función (ya que también hace su propia limpieza). Se podrían haber extraído datos con cola_extraer, pero sería más lento. Después, para evitar trabajar directamente con el dato cola se pueden hacer algunas funciones auxiliares que de hecho ya se han usado en el código anterior, pero esas van más para un usuario de nuestro código: Código
Título: Re: Puntero doble Publicado por: LadyWin en 18 Agosto 2021, 04:32 am Gracias por el tiempo que se tomaron, pude resolver el tema de la sintaxis en la funcion agregarElemento, cree la variable nuevo pero sin puntero, el problema es que en otros modulos me salen otros problemas que no puedo resolverlo por este metodo, probe infinitas formas pero no avanzo, asi que creo que lo mejor sera repasar el tema en mayor profundidad, de igual manera aprendi bastante, gracias nuevamente ;-) ;-) ;-) |