Précédent   Forum du club des développeurs et IT Pro > C et C++ > C
C Forum d'entraide technique sur le langage C. Avant de poster -> F.A.Q. C, Avant de poster.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 29/12/2012, 23h08   #1
44Magnum
 
Anthony
Inscription : 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...
44Magnum est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/12/2012, 23h38   #2
Winjerome
Modérateur
 
Avatar de Winjerome
 
Homme Jérôme
Inscription : septembre 2009
Messages : 5 331
Détails du profil
Informations personnelles :
Nom : Homme Jérôme
Âge : 26
Localisation : France, Pyrénées Atlantiques (Aquitaine)

Informations forums :
Inscription : septembre 2009
Messages : 5 331
Points : 13 442
Points : 13 442
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.
Winjerome est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 30/12/2012, 13h12   #3
44Magnum
 
Anthony
Inscription : novembre 2010
Messages : 27
Détails du profil
Informations personnelles :
Nom : Anthony

Informations forums :
Inscription : novembre 2010
Messages : 27
Points : -3
Points : -3
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...
44Magnum est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2012, 14h05   #4
Winjerome
Modérateur
 
Avatar de Winjerome
 
Homme Jérôme
Inscription : septembre 2009
Messages : 5 331
Détails du profil
Informations personnelles :
Nom : Homme Jérôme
Âge : 26
Localisation : France, Pyrénées Atlantiques (Aquitaine)

Informations forums :
Inscription : septembre 2009
Messages : 5 331
Points : 13 442
Points : 13 442
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".
Winjerome est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 30/12/2012, 14h12   #5
44Magnum
 
Anthony
Inscription : novembre 2010
Messages : 27
Détails du profil
Informations personnelles :
Nom : Anthony

Informations forums :
Inscription : novembre 2010
Messages : 27
Points : -3
Points : -3
Ah exact, merci dsl je suis novice en c lol , j'essaie tout ça et je vous tiens au courant, merci encore
44Magnum est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2012, 15h39   #6
44Magnum
 
Anthony
Inscription : novembre 2010
Messages : 27
Détails du profil
Informations personnelles :
Nom : Anthony

Informations forums :
Inscription : novembre 2010
Messages : 27
Points : -3
Points : -3
En fait le truc chiant aussi c'est que le buffer doit etre alloué DANS la fonction.... Je ne comprend vraiment rien
44Magnum est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/12/2012, 20h28   #7
44Magnum
 
Anthony
Inscription : novembre 2010
Messages : 27
Détails du profil
Informations personnelles :
Nom : Anthony

Informations forums :
Inscription : novembre 2010
Messages : 27
Points : -3
Points : -3
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...
44Magnum est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 31/12/2012, 10h16   #8
diogene
Responsable Modération
 
Avatar de diogene
 
Homme Patrick Gonord
Enseignant Chercheur
Inscription : juin 2005
Messages : 5 488
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 488
Points : 13 125
Points : 13 125
Citation:
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);
Citation:
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 !
diogene est déconnecté   Envoyer un message privé Réponse avec citation 10
Réponse
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 11h20.


 
 
 
 
Partenaires

Hébergement Web