Home > Software engineering >  C parent child shared memory, prints without spacing
C parent child shared memory, prints without spacing

Time:02-04

I am currently working on a lab for one of my classes that involves shared memory between a parent and child process. The data is generated by the child, and written into memory. The parent then prints the contents of the memory. My problem is that I cannot seem to get proper spacing between data points. The algorithm used to generate data Collatz conjecture, which is n = n/2 if n is even, and n = 3*n 1 if n is odd. So an input of 8 would generate the sequence 8 4 2 1, but I keep getting "8421" or " 8421" or "8421 " ect.

I have tried many combinations of placement of spaces in both parent (printf) and child (sprintf). For example in the child:

sprintf(ptr, "%d", n); 
sprintf(ptr, "%d ", n); 
sprintf(ptr, " %d", n); 
sprintf(ptr, " %d ", n);

and in the parent

printf("%s", (char *)ptr);
printf("%s ", (char *)ptr);
printf(" %s", (char *)ptr);
printf(" %s ", (char *)ptr);
#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <wait.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <string.h>
#include <sys/mman.h>

int main(int argc, char** argv){
    const int SIZE = 4096;//Shared memory size
    const char* name = "COLLATZ";//Shaired Memory Name
    int n = atoi(argv[1]);
    pid_t pid = fork();//process divergence

    int shm_fd;//shared memory file descriptor
    void *ptr;//shared memory pointer
    shm_fd = shm_open(name, O_CREAT | O_RDWR, 0666);//create shared memory object
    ftruncate(shm_fd, SIZE);//configure size of the shared memory
    ptr = mmap(0, SIZE, PROT_WRITE, MAP_SHARED, shm_fd, 0);//memory map the shared memory object

    if(pid == 0){
        while(n > 1){//child
            //write to shared memory
            sprintf(ptr, "%d ",n);
            char *a = (char *) &n;
            ptr  = strlen(a);

            //Callatz conjecture sequence
            if(n % 2 == 0){
                n = n/2;
            } else {
                n = 3 * n 1;
            }
        }
        //write to shared memory
        sprintf(ptr, "%d ",n);
        char *a = (char *) &n;
        ptr  = strlen(a);
    }else if(pid > 0){//parent
        wait(NULL);
        printf("%s", (char *)ptr);//Read from shared memory
        printf("\n");
    }
    shm_unlink(name);//close shared memory
    return 0;
}

CodePudding user response:

The issue is how you are adding to your ptr variable. setting a to (char*) &n will have a point to your int value, and since your int value is less than a 256 (a byte of memory), then it will be read as 1 char and read with length 0.

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

int main()
{
    char *ptr = malloc(4096);
    int n = 12;
    
/// Writting to buffer section ///
    sprintf(ptr, "%d ", n);
    char *a = &n;
    ptr  = strlen(a);
//////////////////////////////////
    
    // This should print "" if you added to ptr correctly
    printf("\"%s\"", ptr);
    fflush(stdout);
    
    return 0;
}
output: "2 "

To fix this, you should use another way of adding to the pointer. My suggestion would be replacing the writting to buffer section with the following

    int write_len = sprintf(ptr, "%d ", n);
    ptr  = write_len;

If you'd perfer not using the return value of spritnf, you can also do:

    sprintf(ptr, "%d ", n);
    ptr  = strlen(ptr);

CodePudding user response:

Notice that you add to the ptr only the lentgh of the number, and not the length of the entire string.

Change:

sprintf(ptr, "%d ",n);
char *a = (char *) &n;
ptr  = strlen(a);

to:

char buff[100];
sprintf(buff, "%d ",n);
sprintf(ptr, "%s", buff);
ptr  = strlen(buff);
  • Related