2016-08-02 2 views
0

Bonjour J'ai un petit problème avec void * utilisé pour rendre le code plus générique. J'ai écrit une file d'attente fifo (en utilisant la liste chaînée ci-dessous) qui stocke toutes les données qui peuvent être castées en void * (c'est-à-dire struct * comme void *).Retour struct * stocké dans la file d'attente fifo comme void * (le renvoyer par plusieurs fonctions)

Maintenant, j'ai une fonction qui récupère ces données. Mais le problème est que struct qui a 3 champs est retourné avec seulement le premier champ rempli et d'autres 2 sont vides (a été rempli lorsqu'il est placé dans la file d'attente).

Toutes les fonctions comme back(), unwrap'_data_from_node '() et fifo_dequeue() retournent ces données comme void *. Ce qui est plus étrange, c'est que void * peut être casté en struct * dans fifo_dequeue() et contiendra tous les champs remplis de données, alors que retourné depuis fifo_dequeue() le même pointeur retourné n'a qu'un champ rempli (1er champ), et deux sont vides, rien. La méthode sous-jacente supprimant le nœud de la liste chaînée tout en créant pop_back();

void remove_node(doubly_linked_list_t *list, doubly_linked_node_t *old_node) { 

    // if node to delete unspecified return error 
    if (old_node == NULL) { 
     fprintf(stderr, "Node to delete is empty!"); 
     return; 
    } 

    // if node to delete is the only left on the list make empty list 
    if (old_node->next == old_node) // or old_node->prev = old_node 
    { 
     list->head = list->tail = NULL; 
    } else { 
     old_node->prev->next = old_node->next; 
     old_node->next->prev = old_node->prev; 

     if(old_node == list->head) list->head = old_node->next; 
     if(old_node == list->tail) list->tail = old_node->prev; 
    } 

    free(old_node->data); old_node->data = NULL; 
    free(old_node); old_node = NULL; 
} 
+0

Je suppose que le problème est avec des copies memcpy iT pointer juste struct stocké dans les données et non contenues pointeurs de champs. Ainsi, le premier élément peut être maintenu mais les autres sont perdus. Je dois copier comme pop_back supprime et libère des données du noeud dans la liste liée –

+0

'int task_size = sizeof (tâche)' <- qui ne peut pas être correct: 'sizeof * task' est je pense que ce que vous voulez, et à tout rate: 'sizeof' renvoie' size_t', pas 'int'. Aussi tâche_t * tâche; task = (task_t *) tmp_data; 'a l'air moche. Pourquoi pas 'task_t * task = tmp_data;'. Pas besoin de la fonte. C'est une ligne simple, facile à lire –

+0

Ouais mais c'est task_t est seulement le code de test. Je le place pour montrer que quand il est casé en type réel task_t * (de structure) il a tous les champs remplis mais quand je viens d'opérer sur void * (type générique) et je le copie et puis retourne comme nul * alors je suis perdre des champs même si plus tard à la même distribution. Je pense que c'est l'effet de memcpy void * pas le type réel. Bu je ne sais pas comment compenser ce problème. Je ne veux pas perdre de génériques dans ma file d'attente fifo et ma liste chaînée, je ne veux pas non plus faire de désordre en passant des roulettes additionnelles pour sécuriser cette copie. –

Répondre

1

Le problème est avec sizeof()

Vous prenez seulement la taille du pointeur dans cette ligne

int task_size = sizeof(task); 

après, pas assez de données est copié.

Vous devez malloc et copier l'ensemble struct par la taille de struct:

int task_size = sizeof(task_t); 
+0

oui mais les données stockées dans la liste liée sous fifo_queue sont des pointeurs (void * data) –

+0

si vous voulez seulement retourner le pointeur, allez-y. Pas besoin de copier quoi que ce soit. Mais si vous voulez copier la structure entière, vous devez copier par la taille de la structure. – eyalm

+0

ouais mais le problème est que je veux retourner void * de fifo_dequeue() afin de fifo file d'attente pourrait stocker des données typées génériques et être réutilisable. Je pourrais retourner juste ce pointeur de tmp_data et pas mamcpy() mais il y a un autre problème comme avant pop_back() qui enlève le noeud de fifo_queue (liste liée) et alors libre() ce pointeur ainsi je veux faire une copie de il. Peut-être que je devrais supprimer cette désallocation des données –