Publicité
+ Répondre à la discussion
Affichage des résultats 1 à 8 sur 8

Discussion: pile FIFO et memcpy

  1. #1

    Profil pro Anthony
    Inscrit en
    novembre 2010
    Messages
    27
    Détails du profil
    Informations personnelles :
    Nom : Anthony

    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 :
    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
    Responsable FAQ C++
    Avatar de Winjerome
    Homme Profil pro Jérôme
    Inscrit en
    septembre 2009
    Messages
    7 857
    Détails du profil
    Informations personnelles :
    Nom : Homme Jérôme
    Âge : 27
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : septembre 2009
    Messages : 7 857
    Points : 28 904
    Points
    28 904

    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 :
    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 :
    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

    Profil pro Anthony
    Inscrit en
    novembre 2010
    Messages
    27
    Détails du profil
    Informations personnelles :
    Nom : Anthony

    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 :
    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
    Responsable FAQ C++
    Avatar de Winjerome
    Homme Profil pro Jérôme
    Inscrit en
    septembre 2009
    Messages
    7 857
    Détails du profil
    Informations personnelles :
    Nom : Homme Jérôme
    Âge : 27
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations forums :
    Inscription : septembre 2009
    Messages : 7 857
    Points : 28 904
    Points
    28 904

    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

    Profil pro Anthony
    Inscrit en
    novembre 2010
    Messages
    27
    Détails du profil
    Informations personnelles :
    Nom : Anthony

    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

    Profil pro Anthony
    Inscrit en
    novembre 2010
    Messages
    27
    Détails du profil
    Informations personnelles :
    Nom : Anthony

    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

    Profil pro Anthony
    Inscrit en
    novembre 2010
    Messages
    27
    Détails du profil
    Informations personnelles :
    Nom : Anthony

    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

    Homme Profil pro Patrick Gonord
    Enseignant Chercheur
    Inscrit en
    juin 2005
    Messages
    5 664
    Détails du profil
    Informations personnelles :
    Nom : Homme Patrick Gonord
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : juin 2005
    Messages : 5 664
    Points : 13 489
    Points
    13 489

    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 :
    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,...)

Liens sociaux

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •