TiagoM
TiagoM

Reputation: 3526

Shared memory for sharing an array of the same structure

Okay look first thanks for this place :) I would like to create a piece of shared memory to store 30 structures of the same type, but I am getting errors on compile..

struct nota
{
    int n;
    char text[30];
    char titulo[100];
    char login[20];
}

main(){
     int shmID;
     struct nota *evernota;
     struct nota um;

     shmID = shmget(1009, sizeof(struct nota)*30 , 0666 | IPC_CREAT);

     evernota = shmat(shmID, NULL, 0);

     evernota[0] = &um;  //Declaring one note here to the first position of shm..
     evernota[20] = &um;  //Declaring the same note on the 20 position of shm..

     printf("o meu int é %d\n",evernota[0]->n);  //Here I would get the int n of each structure, that should be 0, because its not initialized..
     printf("o meu int é %d\n",evernota[20]->n);  //and there the same n, because I use the same structure on position 0 and 20..  
}

But I have compile errors, someone see where is the problem?? Thanks alot in advance!!!

Upvotes: 0

Views: 2535

Answers (3)

Cavaz
Cavaz

Reputation: 3119

well for starters you need the includes:

#include <stdio.h>
#include <string.h>
#include <sys/shm.h>

then you need the semicolon after struct definition:

struct nota {
    ...
};

Add the flag IPC_EXCL, makes shmget fail if the memory key is already in use (use IPC_PRIVATE instead of 1009 to guarantee the memory segment is new). Then a check on shmID != -1 would be nice, and to copy the references use memcopy:

memcpy(&evernota[0], &um, sizeof(struct nota));  
memcpy(&evernota[20], &um, sizeof(struct nota));

about the printfs, use the . instead of ->. They will print garbage data, they're not automatically 0-initialized on allocation, you have to do it by yourself.

Upvotes: 1

Il-Bhima
Il-Bhima

Reputation: 10880

Ok, there is a lot wrong with this code. You at least need the following includes:

 #include <sys/shm.h>
 #include <stdio.h>

The second problem is that you are not initialising um or evernote at all. This means that for example, evernote[0]->n will contain garbage data. So you should at least have, for example

um.n = 1;

Now comes the problem of copying um to the shared memory segment. You need to copy the contents of the memory defined by the um struct into the evernota array. To do this:

 memcpy(&evernota[0], &um, sizeof(struct nota));  
 memcpy(&evernota[20],&um,sizeof(struct nota));  

NB: memcpy is defined in string.h.

Now finally, to print the contents of the field n in evernota[0] you need only use the dot operator i.e.

 printf("o meu int é %d\n",evernota[20].n);  

I think thats everything.

EDIT: Does the code below still give you segfaults?

   #include <sys/shm.h>
   #include <string.h>
   #include <stdio.h>

   struct nota {
     int n;
     char text[30];
     char titulo[100];
    char login[20];
  };

     int main(){

        int shmID;
        struct nota *evernota;
        struct nota um;

        um.n = 1;
        shmID = shmget(1009, sizeof(struct nota)*30 , 0666 | IPC_CREAT);

        evernota = shmat(shmID, NULL, 0);

        memcpy(&evernota[0], &um, sizeof(struct nota));  
        memcpy(&evernota[20],&um,sizeof(struct nota));  

        printf("o meu int é %d\n",evernota[0].n);  
        printf("o meu int é %d\n",evernota[20].n); 

        return 0; 
      } 

Upvotes: 1

pmod
pmod

Reputation: 11007

Variable um of struct nota type is not initialized. What do you expect to be printed to stdout?

Check missed headers, they should be at least:

#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>

To initialize one element of an array use memcpy:

memcpy(&evernota[0], &um, sizeof(struct nota));

It's always good style to check return values of system function:

   if ((shmID = shmget(1009, sizeof(struct nota)*30 , 0666 | IPC_CREAT) < 0) {
        perror("shmget");
        exit(1);
   }

Upvotes: 1

Related Questions