p
u
b
l
i
c
i
t
é
publicité

Discussion: pile FIFO et memcpy

  1. #1

    Inscrit en
    novembre 2010
    Messages
    27
    Détails du profil
    Informations forums :
    Inscription : novembre 2010
    Messages : 27
    Points : -3
    Points
    -3

    Par défaut pile FIFO et memcpy

    Salut a tous,

    Voila j'ai un souci, je suis en train de creer une FIFO en c qui peut contenir n'importe quel type de donnée, ma structure a donc un pointeur sur void comme element principal.. lorsque je veux retirer mon premier element de ma file (la tete), je dois d'abord sauvegarder son contenu dans un buffer (void * aussi), pour copier les données, jutilise alors memcpy, cependant j'ai un souci, lorsque je le fais, j'arrive a afficher le contenu du buffer DANS la fonction (dequeue), mais pas dans le MAIN...

    Je ne comprend pas d'ou vien l'erreur... voici le code

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <assert.h>
    #include <errno.h>
    #include <unistd.h>
    #include <sys/uio.h>
    #include <pthread.h>
    #include <sched.h>
    #include "queue.h"
     
    struct queue {
     
      pthread_mutex_t mutex;
      pthread_cond_t cond;
      size_t size_max;
      size_t total_size;
      struct list *list;
     
    };
     
    struct list {
      void * elt;
      size_t elt_size;
      struct list* next;
     
    };
     
    int dequeue(struct queue *q,void *buf,size_t size, int blocking){
     
      struct list* tmp;
      pthread_mutex_lock(&q->mutex);
     
      if (q->list == NULL){
        errno = EAGAIN;
        pthread_mutex_unlock(&q->mutex);
        return -1;
      }else if (size < q->list->elt_size){
        errno=EMSGSIZE;
        pthread_mutex_unlock(&q->mutex);
        return -1;
      }		
      buf=malloc(size);
      memcpy(buf,q->list->elt,size); // C'est ici que je copie le contenue de l'element a virer dans le buffer de sauvegarde passé en parametre de la fonction[
     
      printf("Buffer de dequeue : %s\n",(char *)buf);// Je teste sur un char *, sa s'affiche correctement, mais des que j'essaie d'afficher dans le main, sa foire... 
     
      if(q->list->next != NULL){
        tmp=q->list;
        q->list=q->list->next;
        free(tmp);
      }else{
        free(q->list);
        q->list= NULL;
      }
      q->total_size-=size;
      pthread_mutex_unlock(&q->mutex);
      return size;
    }
     
    int main() {
      struct queue *exemple = queue_new(100);
      const char *buf = "bonjour";
      const char *buf2 = "comment";
      void * cpy=NULL;// LE BUFFER DANS LEQUEL JE MET LA VALEUR RETIRÉE DE LA FILE AVEC DEQUEUE
     
      enqueue(exemple,buf,7,0);// Enqueue fonctionne tres bien
      enqueue(exemple,buf2,7,0);
      dequeue(exemple,cpy,7,0);// Appel a la fonction qui nous interesse
     
      printf("BUFFER  : %s\n", (char * )cpy);// SA FOIRE ICI
     
      if(exemple->list!= NULL){
        printf("TETE %s\n",(char *)exemple->list->elt);
     
      }
      return 0;
     
    }
    Je ne comprend vraiment pas d'ou vient l'erreur... c'est un pointeur sur void qui est passé en parametre, je ne vois pas pourquoi je ne peux pas acceder a ce bloc de memoire a partir du main... merci d'avance pour votre aide, je bloque severe, j'ai essayé avec des & dans memcpy mais sa sert a rien les 2 arguments sont des pointeurs de meme type...

  2. #2
    Expert Confirmé Sénior
    Avatar de Winjerome
    Homme Profil pro
    Inscrit en
    septembre 2009
    Messages
    8 325
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : septembre 2009
    Messages : 8 325
    Points : 30 478
    Points
    30 478

    Par défaut

    Bonsoir,

    buf situé en paramètre de la fonction dequeue() est une copie du pointeur cpy. Tu ne fais que modifier la copie et non le pointeur original.

    Il te faut utiliser un pointeur sur pointeur :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    int dequeue(struct queue *q,void **buf,size_t size, int blocking){
    
    *buf = malloc(size);
    memcpy(*buf,q->list->elt,size);
    
    printf("Buffer de dequeue : %s\n",(char *) *buf);
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dequeue(exemple,&cpy,7,0);
    Ne pas oublier de libérer la mémoire (queue_free() ou fonction du genre + free(cpy)) à la fin.

  3. #3

    Inscrit en
    novembre 2010
    Messages
    27
    Détails du profil
    Informations forums :
    Inscription : novembre 2010
    Messages : 27
    Points : -3
    Points
    -3

    Par défaut

    Ah merci beaucoup pour cette reponse.. j'ai juste oublier que je n'ai pas le droit de modifier la definition de dequeue dans le .h a savoir

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int dequeue(struct queue *q,void *buf,size_t size, int blocking);
    Dsl c'est un projet en fait et le prof interdit de modifier ça... j'ai oublié de le preciser...

  4. #4
    Expert Confirmé Sénior
    Avatar de Winjerome
    Homme Profil pro
    Inscrit en
    septembre 2009
    Messages
    8 325
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : septembre 2009
    Messages : 8 325
    Points : 30 478
    Points
    30 478

    Par défaut

    Dans ce cas, effectue l'allocation en dehors de ta fonction dequeue().

    Remarque : la chaîne "bonjour" compte 8 éléments : 'b', 'o', 'n', 'j', 'o', 'u', 'r' et le '\0' final, de même "comment".

  5. #5

    Inscrit en
    novembre 2010
    Messages
    27
    Détails du profil
    Informations forums :
    Inscription : novembre 2010
    Messages : 27
    Points : -3
    Points
    -3

    Par défaut

    Ah exact, merci dsl je suis novice en c lol , j'essaie tout ça et je vous tiens au courant, merci encore

  6. #6

    Inscrit en
    novembre 2010
    Messages
    27
    Détails du profil
    Informations forums :
    Inscription : novembre 2010
    Messages : 27
    Points : -3
    Points
    -3

    Par défaut

    En fait le truc chiant aussi c'est que le buffer doit etre alloué DANS la fonction.... Je ne comprend vraiment rien

  7. #7

    Inscrit en
    novembre 2010
    Messages
    27
    Détails du profil
    Informations forums :
    Inscription : novembre 2010
    Messages : 27
    Points : -3
    Points
    -3

    Par défaut

    salut

    si j'ai un pointeur void

    comment je fais pour bouger le pointeur ?

    si j'ai void * buf, comment je fais pour avancer ce pointeur de n octets sur mon buf , buf += n sa ne fonctionne pas on dirait...

  8. #8
    Expert Confirmé Sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : juin 2005
    Messages : 5 761
    Points : 14 013
    Points
    14 013

    Par défaut

    En fait le truc chiant aussi c'est que le buffer doit etre alloué DANS la fonction.... Je ne comprend vraiment rien
    Tu peux toujours utiliser la solution de Winjerome en explicitant le cast : (même si on se demande pourquoi ce prototype inadapté est imposé) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    int dequeue(struct queue *q,void *buf,size_t size, int blocking)
    {
       *(void**)buf = malloc(size);
      ...
    }
    void * cpy;
    dequeue(exemple,&cpy,7,0);
    si j'ai void * buf, comment je fais pour avancer ce pointeur de n octets sur mon buf , buf += n
    Ce genre de calcul impose au compilateur de connaitre la taille de l'objet pointé, ce qui n'est pas le cas pour un void*. Il faut donc restituer le type exact du pointeur (par un cast, une assignation à un pointeur du bon type,...)
    Publication : Concepts en C

    Mon avatar : Glenn Gould

    --------------------------------------------------------------------------
    Une réponse vous a été utile ? Remerciez son auteur en cliquant le pouce vert !

Discussions similaires

  1. héritage pile FiFo Lifo
    Par jockerse dans le forum C++/CLI
    Réponses: 3
    Dernier message: 08/04/2014, 11h43
  2. Pile FIFO avec un Trigger
    Par takoha dans le forum PHP & MySQL
    Réponses: 1
    Dernier message: 19/12/2010, 12h15
  3. [Conception] Pile FIFO
    Par zoullou dans le forum Général Java
    Réponses: 12
    Dernier message: 17/03/2006, 10h08
  4. [TASM] Déclarer le segment de pile
    Par cipher dans le forum x86 16-bits
    Réponses: 2
    Dernier message: 01/10/2002, 03h58
  5. Recherche code d'un fifo,ou explication
    Par don-diego dans le forum C
    Réponses: 8
    Dernier message: 25/07/2002, 10h26

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo