CodeRed
CodeRed

Reputation: 127

accessing a structure member in a shared memory "in C"

I am trying to write a code that shares a structure type, but im getting segmentation error when tryign to write in a structure member in the shared memory, the shared memory is between a parent and child process. as im showing in the code, im just tryin to access the struct member for now, so i can use semaphore later for synch.

Thanx in advance.

typedef struct file
{
    char *shmPtr;
} file_entry;

int main (void)
{

    int shmid;
    int n;
    file_entry *entries;

    if (fork() == 0) {
        /*wait for a while*/

        if ((shmid = shmget(20441, sizeof(file_entry), 0666)) == -1) {
            printf("shmget");
            exit(2);
        }

        entries = (file_entry*) shmat(shmid, 0, 0);
        if (entries->shmPtr == (char *) -1) {
            printf("problem2");
            exit(2);
        }

        printf("\nChild Reading ....\n\n");
        printf("%s\n", entries->shmPtr[0]);
        printf("%s\n", entries->shmPtr[1]);
        putchar('\n');
        printf("\nDone\n\n");
    } else {
        if ((shmid = shmget(20441, sizeof(file_entry), IPC_CREAT | 0666)) == -1) {
            printf("problem3");
            exit(2);
        }

        entries = (file_entry *) shmat(shmid, 0, 0);
        if (entries->shmPtr == (char *) -1) {
            printf("problem4");
            exit(2);
        }
        printf("done attachment");  /*the parent prints this statment, then segmentation fault*/

        entries->shmPtr[0]='a';
        entries->shmPtr[1]='b';
        putchar('\n');

        wait();
        shmdt(&shmid);
    }
    exit(0);
}

Upvotes: 1

Views: 3322

Answers (1)

Greg Inozemtsev
Greg Inozemtsev

Reputation: 4671

shmat returns a pointer to the shared memory area. In your code, after the call to shmat, entries points to the shared region. You are then treating the first few bytes of that shared area as a pointer to char (shmPtr). The value of shmPtr is uninitialized, and it points to some random location. Then you try to write to it and get a segfault.

Edit:

As Richard suggested, you could get rid of the struct and just use a char *. However, I'm guessing the reason you are using a struct and not just a char * is that you are planning to add some extra fields to the struct in the future. If that's the case, you can use a flexible array member:

typedef struct file
{
    int flag;
    int blah;
    char shmPtr[];
} file_entry;

and the allocation becomes

shmget(20441, sizeof(file_entry) + bufsize, IPC_CREAT | 0666)

Of course, if the buffer size is fixed, you could just hardcode it:

typedef struct file
{
    int flag;
    int blah;
    char shmPtr[BUFSIZE];
} file_entry;

/* ... */
shmget(20441, sizeof(file_entry), IPC_CREAT | 0666)

Upvotes: 1

Related Questions