UTNianos

Versión completa: [Info I] Ejercicio recup.
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Tengo que dar recu del segundo parcial la semana que viene y recién me puse hoy a hacer por millonésima vez los ejercicios.
Este es un ejercicio que me tomaron en el recuperatorio del segundo parcial en Diciembre y pedia:
Hacer una funcion con el siguiente protoipo: void insert (nodo **list, void *d_ata) (en realidad la lista era con puntero simple pero me parece que queda mejor con puntero doble y el profesor nos deja hacerlo asi si queremos), luego deberian ir colocandose los nodos en orden alfabetico (yo ahora lo hice por orden de llegada para ver si anda esta parte)

Escribi el siguiente codigo, pero me tira violacion de segmento y el problema esta al igualar la estructura void previamente casteada con la estructura data del nodo nuevo, lo se porque si corto esa linea no me tira la violacion de segmento.
Otra forma seria copiar componente por componente de la estructura void a la estructura del nuevo nodo...

Algun alma caritativa que vea donde yo no veo y me diga en que le estoy pifiando?
Saludos y gracias! =)


#include <stdio.h>
#include <stdlib.h>

struct Data {
char apellido[21];
int legajo;
};

typedef struct Data s_data;

struct Nodo {
s_data data;
struct Nodo *sig;
};

typedef struct Nodo nodo;

void insert (nodo **list, void *data);
void imp_lista (nodo *list);

//**********************************************************************************************************//

int main () {

nodo *lista;
lista=NULL;

s_data Data;

printf ("\nApellido: ");
fgets (Data.apellido,20,stdin);

while (Data.apellido[0]!='\n') {
insert (&lista,(void*)&Data);
imp_lista (lista);
printf ("\nApellido: ");
fgets (Data.apellido,20,stdin);
}
return 0;
}

//**********************************************************************************************************//


void insert (nodo **list, void *d_ata) {

nodo *nuevo;
nodo *ant,*act;
s_data dato;

dato=(*(s_data*)d_ata);

printf ("\nApellido: %s", dato.apellido);


nuevo = (nodo*) malloc (sizeof(nodo));

if (nuevo==NULL) {
printf ("\nNo hay memoria disponible.");
return;
}

nuevo->data=dato;
nuevo->sig=NULL;

if (*list==NULL) {
*list=nuevo;
}

else {
act=*list;
while (act->sig!=NULL)
act=act->sig;

act->sig=nuevo;
}
}

//**********************************************************************************************************//

void imp_lista (nodo *list) {

int i=1;

if (list==NULL) {
printf ("\nLista vacia.");
}

else {
while (list!=NULL) {
printf ("\n%d. Apellido: %s",i,list->data);
list=list->sig;
i++;
}
}
}

¿Por qué tiene que ser void el segundo puntero? Dentro de la función lo volvés a convertir al tipo s_data, o sea que el paso intermedio por void* es innecesario. Y en todo caso no hace falta castear a void*. Por otra parte el problema no parece estar en la línea que mencionás sino en la 91, donde dice printf ("\n%d. Apellido: %s",i,list->data); debería decir printf ("\n%d. Apellido: %s",i,list->data.apellido);
Tiene que ser void porque asi lo dice el enunciado, a mi tambien me parece al dope.
En realidad a mi lo unico que me piden es la funcion insert, todo lo demas lo hice para probarla.
Y tenes razon, el error estaba ahi.. creo que ya estoy negado con esta materia -__-

Muchas gracias!
Tiene que ser *void porque la quieren hacer universal, o se la funcion solo se encarga de crear la lista y de poner el pintero a void donde va, lo unico que haces cuando cambias un programa es el tipodato s_data, no se si entiende.. igual medio al pedo me parece tmbn. ademas estas llenado un dato no un *dato.. pero bueno, espero que te valla bien julian! sos uno de lo que mas te esforzaste en la atedra, igual siempre con esos errores colgados jajaja mucha mierda!
(21-02-2012 17:47)besthandball2010 escribió: [ -> ]Tiene que ser *void porque la quieren hacer universal, o se la funcion solo se encarga de crear la lista y de poner el pintero a void donde va, lo unico que haces cuando cambias un programa es el tipodato s_data, no se si entiende.. igual medio al pedo me parece tmbn. ademas estas llenado un dato no un *dato.. pero bueno, espero que te valla bien julian! sos uno de lo que mas te esforzaste en la atedra, igual siempre con esos errores colgados jajaja mucha mierda!

jaja, si.. esos errores colgados me la van a hacer recursar si sigo asi
suerte a vos con fisica y quimica gatun!
Si la querés hacer universal, primero tendrías que tener la estructura definida así:


struct Nodo {
void *data;
struct Nodo *sig
};


Tendrías que pasarle un puntero a la función insert, para el que previamente hayas pedido memoria con malloc, es decir parte del main quedaría así:


s_data *Data;
Data = (s_data *)malloc(sizeof(s_data));

/* Acá rellenás la estructura */

insert(&lista, Data);


Y después adentro de la función insert no hay que hacer el casteo a s_data, llegado el momento directamente asignás el puntero en el nodo.


nuevo->data = d_ata;


El resultado de esto es que todos los nodos de la lista tienen un campo apuntando a "algo", que puede ser un int, un char, un vector, una estructura gigantesca o cualquier otro tipo de datos, pero lo importante es que los nodos no distinguen entre esos tipos, sino que los ven a todos como void*.

Pero todo esto te agrega la necesidad de liberar todos esos datos justo antes de liberar el nodo, por eso no sé si es realmente lo que estaban buscando al hacer el ejercicio.
URLs de referencia