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);