Dereferencing error en utilisant des messages

Dereferencing error en utilisant des messages - C - Programmation

Marsh Posté le 18-05-2005 à 01:07:46    

Voilà le code incriminé :
 

Code :
  1. #include "global.h"
  2. #include <stdio.h>
  3. #include <signal.h>
  4. #include <sys/types.h>
  5. #include <sys/ipc.h>
  6. #include <sys/msg.h>
  7. #include <fcntl.h>
  8. #include <errno.h>
  9. #include <string.h>
  10. int main(int argc, char * argv[])
  11. {
  12.     int msgId = atoi(argv[1]);
  13.     int file;
  14.     struct msgbuf * msgp;
  15.     t_mess mess;
  16.     if (argc != 2){
  17.         fprintf(stdout, "Usage : routeur <n° de la file>\n" );
  18.         exit(0);
  19.     }
  20.     signal(SIGHUP, lireRoute);
  21.     lireRoute(SIGHUP);
  22.     file = msgget(msgId, O_RDWR);
  23.     while ( msgrcv(msgId, msgp, TAILLE_MAX_MESS, 0, 0) != -1 ) {
  24.         mess.dest = msgp->mtext[0];
  25.         mess.mess = msgp->mtext[1];
  26.         mess.type = msgp->mtype;
  27.     }
  28.     perror(strerror(errno));
  29. }


 
à la compilation j'obtiens un splendide :

Code :
  1. routeur.c: In function `main':
  2. routeur.c:71: dereferencing pointer to incomplete type
  3. routeur.c:72: dereferencing pointer to incomplete type
  4. routeur.c:73: dereferencing pointer to incomplete type


 
Si vous en doutez encore, je suis pas une flèche en C, donc si c'est con, allez y, lachez vous.
 
Je ne comprend pas pourquoi ne n'arrive pas à récupérer les champs de msgp...
 
Une idée ?


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Marsh Posté le 18-05-2005 à 01:07:46   

Reply

Marsh Posté le 18-05-2005 à 10:34:33    

brisssou a écrit :

Voilà le code incriminé :
 

Code :
  1. int main(int argc, char * argv[])
  2. {
  3.    struct msgbuf * msgp;
  4.    while ( msgrcv(msgId, msgp, TAILLE_MAX_MESS, 0, 0) != -1 )
  5.    {
  6.       mess.dest = msgp->mtext[0];
  7.       mess.mess = msgp->mtext[1];
  8.       mess.type = msgp->mtype;
  9. }


 
à la compilation j'obtiens un splendide :

Code :
  1. routeur.c: In function `main':
  2. routeur.c:71: dereferencing pointer to incomplete type
  3. routeur.c:72: dereferencing pointer to incomplete type
  4. routeur.c:73: dereferencing pointer to incomplete type




Heureusement, sinon tu aurais un superbe plantage...

  • Comment est défini 'struct msgbuf' ?
  • Comment est initialisé le pointeur msgp ?


Message édité par Emmanuel Delahaye le 18-05-2005 à 10:35:02

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 18-05-2005 à 11:59:17    

en fait, la structure est définie par le système, c'est dans type.h, ça marche avec les messages...
 
et le pointeur n'est pas initialisé par moi.
 
est-ce qu'un (*msgp).mtext ne serait pas ma solution ?
je testerai ce soir...

Reply

Marsh Posté le 18-05-2005 à 12:57:42    

Ta structure est déclarée mais pas définie, tu peux donc en créer des pointeurs mais tu ne peux pas les déréférencer (*msgp et msgp-> sont interdit).
 
Solution : la définir avant de l'utiliser, par exemple :

#define MSGSZ     128
 
typedef struct msgbuf {
         long    mtype;
         char    mtext[MSGSZ];
         } message_buf;

Reply

Marsh Posté le 18-05-2005 à 13:29:20    

mais pourtant, dans le man de msgsnd et msgrcv :
 

Citation :


NAME
       msgop - message operations
 
SYNOPSIS
       #include <sys/types.h>
       #include <sys/ipc.h>
       #include <sys/msg.h>
 
       int msgsnd(int msqid, struct msgbuf *msgp, size_t msgsz, int msgflg);
 
       ssize_t  msgrcv(int msqid, struct msgbuf *msgp, size_t msgsz, long msg-
       typ, int msgflg);
 
DESCRIPTION
       To send or receive a message, the calling process allocates a structure
       of the following general form:
 
            struct msgbuf {
                 long mtype;     /* message type, must be > 0 */
                 char mtext[1];  /* message data */
            };
 
       The  mtext  field is an array (or other structure) whose size is speci-
       fied by msgsz, a non-negative integer value.  Messages of  zero  length
       (i.e.,  no  mtext  field)  are  permitted.  The mtype field must have a
       strictly positive integer value that can be used by the receiving  pro-
       cess for message selection (see the section about msgrcv).


 
alors en fait, ça voudrait dire que la structure n'est qu'un exemple... en tout cas, c'est ce que je viend de comprendre en lisant la VO du man... en françqis, c'était pas clair...
 
alors, je doit comprendre quoi ? il faut que je déclare la strut, comme tu me le dis ?
 
merci en tout cas, à tous.

Reply

Marsh Posté le 18-05-2005 à 13:39:31    

Oui il faut que tu déclares toi même la struct, ce qui te permet au passage de définir la taille que tu préfères pour mtext.
 
PS : TAILLE_MAX_MESS devrait être égale à MSGSZ en prenant mon exemple.


Message édité par Tarabiscote le 18-05-2005 à 13:43:25
Reply

Marsh Posté le 18-05-2005 à 13:43:29    

brisssou a écrit :

en fait, la structure est définie par le système, c'est dans type.h, ça marche avec les messages...


Tout ce que j'ai trouvé, c'est une définition 'générique'

struct msgbuf;


dans usr/include/linux/syscalls.h. C'est donc bien à l'utilisateur de préciser ce qu'il veux. Vu du système, c'est comme un pointeur anonyme.

Citation :

et le pointeur n'est pas initialisé par moi.



*/home/edelahaye/c-dev/essai/essai/src/essai.c:43: warning: 'msgp' might be used uninitialized in this function  


En tout cas, il n'est pas initialisé par ce code...


/* standard */
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
 
/* POSIX.1 */
#include <fcntl.h>
 
/* Unix V5 */
#include <sys/msg.h>
 
/* -ed- retro engineering... */
#define TAILLE_MAX_MESS 16
typedef struct
{
    int dest;
    int mess;
    int type;
}
t_mess;
 
/* Selon le 'man' */
struct msgbuf
{
    long mtype;
    char mtext[TAILLE_MAX_MESS];
};
 
static void lireRoute(int signum)
{
   (void) signum;
}
 
int main(int argc, char * argv[])
{
    int msgId = atoi(argv[1]);
    int file;
    struct msgbuf *msgp;
    t_mess mess;
     
    if (argc != 2)
    {
        fprintf(stdout, "Usage : routeur <n° de la file>\n" );
        exit(EXIT_FAILURE);
    }
    signal(SIGHUP, lireRoute);
    lireRoute(SIGHUP);
    file = msgget(msgId, O_RDWR);
 
    while ( msgrcv(msgId, msgp, TAILLE_MAX_MESS, 0, 0) != -1 )
    {
        mess.dest = msgp->mtext[0];
        mess.mess = msgp->mtext[1];
        mess.type = msgp->mtype;
    }
    return 0;
}


Message édité par Emmanuel Delahaye le 18-05-2005 à 13:52:10

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 18-05-2005 à 13:47:16    

char mtext[1];
->
char mtext[TAILLE_MAX_MESS];


Message édité par Tarabiscote le 18-05-2005 à 13:48:54
Reply

Marsh Posté le 18-05-2005 à 13:51:29    

Tarabiscote a écrit :

char mtext[1];
->
char mtext[TAILLE_MAX_MESS];


Ok, étant donné que c'est l'utilisateur qui définit le type complet, on peut faire ça. Je corrige. Mais il subsiste le problème de l'initialisation.
 
Maintenant que le type est complet, on peut faire

   struct msgbuf msgp;


et passer l'adresse...


Message édité par Emmanuel Delahaye le 18-05-2005 à 13:54:38

---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Marsh Posté le 18-05-2005 à 14:49:47    

merci à tous, vraiement !

Reply

Marsh Posté le 18-05-2005 à 14:49:47   

Reply

Marsh Posté le 18-05-2005 à 23:19:33    

merci beaucoup, tout a fonctionné !
 
il manquait simplement l'initialisation de la structure, comme tu le disait, et j'ai eu un soucis tordu : ça ne fonctionne qu'en root, sinon, la file ne se crée pas.
 
merci beaucoup à tout le monde !


---------------
HFR - Mes sujets pour Chrome - Firefox - vérifie les nouveaux posts des topics suivis/favoris
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed