Search code examples
cstructmallocwaitshared-memory

memory and pass values in a Pointer in shared memory


I'm trying to pass some values between a parent and 10 child processes with shared memory and active wait.

Some values in the struct are pointers to allocate outside dynamic memory The error is showing when i'm trying to write a number in a string to pass a path file with numbers, but I can't since the memory is not there, I can only do it without a number.

typedef struct {
    char *path[10];
    char *word[10];
    int number_ocurrency[10];
    int flag[10];
} shared_data_type;

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>

int main(int argc, char *argv[]) {
    int fd;
    int data_size = sizeof(shared_data_type),i;
    pid_t pid;
    shared_data_type *shared_data;

    if((fd = shm_open("/ex06_searchWord", O_CREAT|O_RDWR|O_TRUNC, S_IRUSR|S_IWUSR))==-1)
    {
        perror("Error at shared memory allocation!\n");
        return 0;
    }
    ftruncate (fd, data_size);
    shared_data = (shared_data_type *)mmap(NULL,data_size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
    for(i=0; i<10;i++){
        shared_data->flag[i]=0;
        pid=fork();
        if (pid == -1)
        {
            printf("Error at fork!\n");
            return -1;
        }

        if (pid == 0) { /* reader */
            while(!shared_data->flag[i]);
            FILE *file;
            file = fopen(shared_data->path[i], "r");
            if (file == NULL)
            {
                printf("Could not open/find the specified file.\n");
                return -1;
            }
            int size = 0;
            char readChar=NULL;
            char *msg = NULL;
            while((readChar = fgetc(file)) != EOF) {
                msg = (char *) realloc(msg, size+1);
                *(msg + size) = readChar;
                size++;
            }
            *(msg + size) = '\0';

            int count = 0;
            while(msg = strstr(msg, shared_data->word[i]))
            {
                count++;
                msg++;
            }
            shared_data->number_ocurrency[i]=count;
            exit(0);
        }
        if(pid>0){
            shared_data->word[i]="SCOMP";
            char path[16]="files/file1.txt";
            shared_data->path[i]=malloc(sizeof(path)+1);
            sprintf(shared_data->path[i],"files/file%d.txt",i);
            //shared_data->path[i]= "files/file.txt";
            shared_data->number_ocurrency[i]=0;
            shared_data->flag[i]=1;
        }
    }
    for(i=0; i<10;i++){
        wait(NULL);
    }


    for(i=0; i<10;i++){
        printf("The word %s in the son %d appeared: %d times\n",shared_data->word[i],i,shared_data->number_ocurrency[i]);
    }
    if (munmap(shared_data, data_size) == -1)
    {
        perror("Error at unmap!\n");
        return 0;
    }

    if(shm_unlink("/ex06_searchWord")==-1){
        perror("Error at unlink!\n");
        return 0;
    }
    return 0;
}

Solution

  • When you share bytes between processes, you need to make sure those bytes contain something that is meaningful and understandable to all the processes that are going to use it. Putting pointers to memory that isn't shared in shared memory makes no sense. And unless all the processes can be guaranteed to map the shared memory at the same address, even putting absolute pointers to shared memory in shared memory makes no sense.

    You can divide the shared memory into "slots" if you want and get the effect of having pointers in shared memory by placing the slot number in shared memory. The slot number will have to be translated to and from an absolute address in each process, taking into account the base address of the mapping.