2013-02-26 2 views
6

J'ai 2 processus (Client et Serveur) qui communiquent via la mémoire partagée.C - Carte dynamique 2D (double pointeur) - Mémoire partagée

J'ai besoin de créer un tableau 2D dynamique (basé sur les paramètres). Le tableau est stocké dans une structure, puis écrit dans le segment partagé.

Je peux écrire le tableau dans la mémoire partagée, mais je ne peux pas le récupérer dans l'autre processus.

Code client:

struct shared_use_st { 
    int  written_by_you; 
    int  **PID_PRI_array; 
}; 
      /* Prepare Dynamic 2D array */ 
     data_store = malloc(/*ROWS*/ 5 * sizeof(int*)); 
     for(i=0;i<5; i++) 
      data_store[i] = malloc(/*COLS*/ 2 * sizeof(int)); 


     /* Prepare Dynamic 2D array - Shared Memory Seg */ 
     shared_stuff->PID_PRI_array = malloc(/*ROWS*/ 5 * sizeof(int*)); 
     for(i=0;i<5; i++) 
      shared_stuff->PID_PRI_array[i] = malloc(/*COLS*/ 2 * sizeof(int)); 


     /* Write PID and PRI to data_store array */ 
     data_store[0][0] = pid; 
     data_store[0][1] = 1; 

     data_store[1][0] = 12345; 
     data_store[1][1] = 2; 

     data_store[2][0] = 12346; 
     data_store[2][1] = 3; 

     data_store[3][0] = 12347; 
     data_store[3][1] = 4; 

     data_store[4][0] = 12348; 
     data_store[4][1] = 5; 

      for(i=0;i<5;i++){ 
       for(x=0;x<=1;x++){ 
        shared_stuff->PID_PRI_array[i][x] = data_store[i][x]; 
       } 
      } 

Code Serveur:

for(i=0;i<5;i++){ 
    printf("PID: %d, PRI:%d\n", shared_stuff->PID_PRI_array[i][0], shared_stuff->PID_PRI_array[i][1]);    
} 

J'obtiens une erreur "Erreur de segmentation".

Merci.

+1

L'adresse de la mémoire partagée est-elle la même dans les deux processus? Si ce n'est pas le cas, les pointeurs ne fonctionneront pas. –

+0

Oui, ils sont identiques :) –

Répondre

5

Même si votre objet shared_stuff est en mémoire partagée, vous n'écrivez pas le tableau dans la mémoire partagée. Vous allouez de l'espace avec malloc, en écrivant des données dans cet espace, puis en mettant des pointeurs vers cet espace dans shared_stuff. malloc alloue de l'espace dans l'espace d'adressage normal du processus en cours, et non dans un segment de mémoire partagée que vous avez créé. Vous devez écrire le contenu du tableau dans la mémoire partagée.

En supposant qu'il y ait suffisamment d'espace pour la baie dans le segment de mémoire partagée, vous devrez gérer les adresses vous-même, sans utiliser malloc. (S'il n'y a pas assez d'espace, vous devez agrandir le segment de mémoire partagée ou transmettre les informations au fil du temps.)

Vous pouvez placer un tableau de longueur variable dans le segment de mémoire partagée comme suit.

D'abord, définir une structure qui contient toutes les informations « gestion » dont vous avez besoin, tels que les dimensions du tableau:

struct StuffStruct 
{ 
    size_t NumberOfRows, NumberOfColumns; 
    … Other information as desired. 
}; 

Créer un pointeur vers cette structure et le mettre à pointer vers le segment de mémoire partagée:

struct StuffStruct *Stuff = shm; // shm contains the address from shmat, performed previously. 

créer un pointeur vers un tableau avec le nombre souhaité de colonnes et de le mettre au point sur le segment de mémoire partagée après que la structure initiale:

int (*data_store)[NumberOfColumns] = (int (*)[NumberOfColumns]) ((char *) Stuff + sizeof *Stuff); 

(Note pour les puristes C: Oui, le standard C ne garantit pas ce qui se passe quand vous faites de l'arithmétique comme ceci. Cependant, toute mise en œuvre fournissant un soutien de mémoire partagée doit fournir un soutien pour ce type de pointeur arithmétique.)

Notez que sizeof *Stuff + NumberOfRows * NumberOfColumns * size(int)doit pas être supérieure à la taille du segment de mémoire partagée. Sinon, vous allez dépasser le segment de mémoire partagée à l'étape suivante.

Pour l'étape suivante, remplissez le tableau avec des données: Affectez des valeurs aux éléments de data_store comme pour un tableau normal à deux dimensions.

Dans le serveur, définissez Stuff de la même manière. Ensuite, après que le client a écrit le segment de mémoire partagée, lisez les numéros de lignes et de colonnes de Stuff. Réglez ensuite data_store de la même manière.Puis lire à data_store.

+0

Désolé, j'ai oublié de mentionner que j'ai ceci ci-dessus; 'Shared_stuff = (struct shared_use_st *) shm;' Où SHM est le résultat de shmat;
\t '/ * attatch segment à l'espace de données */ \t if ((SHM = shmat (shmid, NULL, 0)) == (char *) - 1) \t { \t \t perror ("shmat") \t \t _Exit (1); Printf ("[+] Segment Attatched \ n"); ' J'ai écrit ce morceau de code dans le client, et il sort exactement ce que j'attends; 'printf (" TEST \ n \ n "); pour (i = 0; i <5; i ++) printf ("PID:% d, PRI:% d \ n", shared_stuff-> PID_PRI_array [i] [0], shared_stuff-> PID_PRI_array [i] [1 ]); \t ' –

+0

Votre commentaire correspond à mon diagnostic. Le code dans le client imprime ce que vous attendez car les données se trouvent aux endroits prévus dans l'espace d'adressage du client. Cependant, les données ne sont pas visibles dans l'espace adresse du serveur. Seule la structure pointée directement par 'shared_stuff' est dans le segment partagé, car vous définissez' shared_stuff' pour pointer vers le segment partagé. Les pointeurs à l'intérieur de cette structure pointent vers des endroits à l'extérieur du segment partagé, les lieux alloués par 'malloc'. Comme ces espaces sont en dehors du segment partagé, ils ne sont pas visibles dans le processus serveur. –

+0

Je vois. Si je fais; 'shared_stuff-> written_by_you = 1;' ceci est visible par le processus serveur, car il ne pointe pas en dehors de l'espace adresse de la structure, n'est-ce pas? Comment pourrais-je résoudre le problème? Merci! –

Questions connexes