Thread: Trying to add an array of Integers to a POSIX Shared memory Object

  1. #1
    Registered User
    Join Date
    Mar 2018
    Posts
    1

    Trying to add an array of Integers to a POSIX Shared memory Object

    Greetings all, I am really new to C and have been using it for about 1 month now at most. I am attempting to store an array from a function into a shared memory object, but I am unsure of how do so.

    I know how to do it with Strings, but not really with an array of integers. The code is supposed to generate a collatz sequence of integers and add it to the shared memory object for another process/program to access it. Here is the code:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/shm.h>
    #include <sys/stat.h>
    #include <sys/mman.h>
    #include <fcntl.h>
    #include <string.h>
    #include <unistd.h>
    
    int *calcCollatz(int n) {
        int solution;
    
        int *collatzSeq = malloc(sizeof(int));
        int j = 0;
        while (n != 1) {
            if (n % 2 == 0) {
                solution = n / 2;
                n = solution;
                collatzSeq[j] = n;
                j++;
                return collatzSeq;
            } else {
                solution = (3 * n) + 1;
                n = solution;
                collatzSeq[j] = n;
                j++;
                return collatzSeq;
            }
        }
    
    
    }
    
    int main(int argc, char *argv[])
    {
        const int SIZE = 4096; //size in bytes of Shared Memory Object
        const char *sharedObj = "Shm"; //name of the Shared memory Object
        int shm_fd; //Shared memory file descriptor
        void *ptrShm; //Pointer to shared memory object
        shm_fd = shm_open(sharedObj, O_CREAT | O_RDWR, 0666); //Create Shared Memory Object
        ftruncate(shm_fd, SIZE); //configure the size of the shared memory object
        ptrShm = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0); //Map the shared memory object in the space of the process
    
        if (ptrShm == MAP_FAILED) {
            printf("Map Failed\n");
            return -1;
        }
    
        sprintf(ptrShm, argv[1]);
        ptrShm += strlen(argv[1]);
    
        sprintf(ptrShm, calcCollatz(atoi(argv[1])));
        ptrShm += sizeof(calcCollatz(atoi(argv[1])));
    
    
        printf("Writing the sequence to a shared memory object!\n");
        return 0;
    }
    The int * collatz sequence method generates a sequence of integers per a collatz sequence until the value reaches 1. Please let me know if you need a clearer explanation.

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,633
    You only malloc enough space for one int in collatzSeq.

    And think about how you are using sprintf in main. The last one receives an int* pointing to an int array and passes that as the 2nd parameter of sprintf. The second parameter of sprintf should be a string.

    And sizeof a pointer is just the size of the pointer, not the size of the array it points to.

    To copy the data you should use memcpy.
    To determine its size, you should have calcCollatz return j through a int* parameter.
    Code:
    // gcc -Wall -o shmcollatz shmcollatz.c -lrt
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <errno.h>
    
    #include <sys/shm.h>
    #include <sys/stat.h>
    #include <sys/mman.h>
    #include <unistd.h>
    #include <fcntl.h>
     
    #define MAX_SEQ_SIZE 1000
    
    void error_exit(const char *msg) {
        if (errno)
            perror(msg);
        else
            fprintf(stderr, "%s\n", msg);
        exit(EXIT_FAILURE);
    }
    
    int *calcCollatz(int n, int *size) {
        int *collatzSeq = malloc(MAX_SEQ_SIZE * sizeof *collatzSeq);
        int j = 0;
        while (n != 1) {
            if (n % 2 == 0)
                n /= 2;
            else
                n = (3 * n) + 1;
            if (j == MAX_SEQ_SIZE)
                error_exit("MAX_SEQ_SIZE reached");
            collatzSeq[j++] = n;
        }
        *size = j;
        return collatzSeq;
    }
     
    int main(int argc, char *argv[]) {
        const int SIZE = 4096; //size in bytes of Shared Memory Object
        const char *sharedObj = "Shm"; //name of the Shared memory Object
    
        if (argc != 2) error_exit("Usage: shmcollatz N\n");
    
        int shm_fd = shm_open(sharedObj, O_CREAT | O_RDWR, 0666);
        ftruncate(shm_fd, SIZE); //configure the size of the shm
    
        char *ptrShm = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);
        if (ptrShm == MAP_FAILED) error_exit("map failed");
        char *pshm = ptrShm;
    
        pshm += sprintf(pshm, "%s", argv[1]);
    
        int size = 0;
        int *a = calcCollatz(atoi(argv[1]), &size);
        memcpy(pshm, a, size * sizeof *a);
        pshm += size * sizeof *a;
    
        // ... etc
        
        return 0;
    }
    A little inaccuracy saves tons of explanation. - H.H. Munro

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. ftruncate, mmap, posix shared memory of changing size.
    By dayalsoap in forum C Programming
    Replies: 3
    Last Post: 01-24-2017, 08:26 PM
  2. Initialize a 1D or 2D array in shared memory (POSIX)
    By Louis Sutter in forum C Programming
    Replies: 5
    Last Post: 12-08-2014, 03:12 PM
  3. shared memory array
    By Amanda Watson in forum C Programming
    Replies: 2
    Last Post: 09-25-2012, 12:36 AM
  4. Posix shared memory Q
    By homer_3 in forum C Programming
    Replies: 10
    Last Post: 03-01-2010, 09:13 PM
  5. Posix shared memory
    By rutledmj in forum C Programming
    Replies: 2
    Last Post: 10-04-2009, 09:42 PM

Tags for this Thread