Amardeep reddy
Amardeep reddy

Reputation: 127

Cannot read shared memory written by one child from the other

My code below creates two children. One child writes to the shared memory and the other tries to read it. However when I see the output printed after reading, it reads a null string instead of "Hello".

I was able to write from a parent and read from a child. But when I try to write from a child and read from the other, I couldn't.

This is my code:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/wait.h>
#include <pthread.h> 
#include <semaphore.h> 
#include <unistd.h> 
#include <sys/ipc.h> 
#include <sys/shm.h>

void spawn_children(int num_child_processes) {
    int pid=0;
    int i=0;

    for(i = 0; i < num_child_processes; i++) {
        pid = fork();
        if(pid < 0) {
            printf("Error\n");
            exit(1);
        } else if (pid == 0) {
            printf("[PID:%0d] Parent=%0d\n",(int) getpid(), (int) getppid());
            if(i==0) {
                // ftok to generate unique key 
                key_t key = ftok("shmfile",65); 

                // shmget returns an identifier in shmid 
                int shmid = shmget(key,1024,0666|IPC_CREAT); 

                // shmat to attach to shared memory 
                char *str = (char*) shmat(shmid,(void*)0,0); 

                str = "Hello";
                printf("Data written in memory: %s\n",str); 

                //detach from shared memory  
                shmdt(str);
            }
            else {
                // ftok to generate unique key 
                key_t key = ftok("shmfile",65); 

                // shmget returns an identifier in shmid 
                int shmid = shmget(key,1024,0666|IPC_CREAT); 

                // shmat to attach to shared memory 
                char *str = (char*) shmat(shmid,(void*)0,0); 

                printf("Data read from memory: %s\n",str); 

                //detach from shared memory  
                shmdt(str);

                // destroy the shared memory 
                shmctl(shmid,IPC_RMID,NULL); 
            }
            exit(0);
        } else  {
            wait(NULL);
        }
    }
}

int main() {
        printf("Main process id= %0d, Parent PID = %0d\n", (int) getpid(), (int) getppid());

        spawn_children(2);

        return 0;
}

Upvotes: 1

Views: 246

Answers (1)

Dan D.
Dan D.

Reputation: 74645

I first thought it was an ordering issue where the read was occurring before the write which still might be occurring. Until I saw that you were attempting to copy a string via assignment.

The issue is that you never actually write into the shared memory because:

str = "Hello";

Doesn't copy the string constant "Hello" into the memory referred to by str but rather makes str point to the string constant. To fix this you should use a means of string copying. I like snprintf.

I thought I should include an example:

#include <stdlib.h>
#include <stdio.h>

int main ()
{
  char * str = malloc(sizeof(char) * 100);
  /* writes Hello into the allocated buffer */
  snprintf(str, 100, "%s", "Hello");
  printf("%s %p\n", str, str);
  free(str); 
  str = NULL;
  /* changes pointer to refer to literal constant */
  str = "Hello";
  printf("%s %p\n", str, str);
}

Upvotes: 2

Related Questions