Reputation: 79
This is my code.
int main(int argc, char *argv[]) {
int shmid;
char *shmc;
char *shmp;
pid_t pid;
shmid = shmget(IPC_PRIVATE, 3 * sizeof(char), 0666 | IPC_CREAT);
pid = fork();
if (pid == 0) {
shmc = (char *) shmat(shmid, NULL, 0);
shmc[0] = argv[1];
shmc[1] = argv[2];
shmc[2] = argv[3];
shmdt(shmc);
}else{
wait(NULL);
shmp =(char*) shmat(shmid,NULL, 0);
char *arg_vec[]={"./test", &shmp[1], &shmp[2],NULL};
execv("./test", arg_vec);
shmdt(shmp);
shmctl(shmid, IPC_RMID, NULL);
}
}
char *arg_vec[]={"./test", &shmp[1], &shmp[2],NULL};
In this line, I was trying to pass 2, 3 to another c program. But it passes 23 and 3. I wonder why and how can I fix the problem. Any help is appreciated. Thank you.
Upvotes: 0
Views: 81
Reputation: 12404
Function execv
expects an array of pointers to strings. What you provide matches the type but not the logic behind:
char *arg_vec[]={"./test", &shmp[1], &shmp[2],NULL};
The addresses you use to initialize the parameter array are only pointers to single char
, no strings.
In shmp
all elements only have 1 byte and they are located at consecutive memory addresses. There is no place for some terminating 0 byte that would make your array a valid string.
You need to provide and initialize more space: (Assuming you can ensure that numbers are only 1 digit)
shmid = shmget(IPC_PRIVATE, 3 * sizeof(char[2]), 0666 | IPC_CREAT);
char (*shmc)[2] = shmat(shmid, NULL, 0);
sprintf(shmc[0], "%d", number[0]);
...
char (*shmp)[2] = shmat(shmid, NULL, 0);
printf("%s, %s\n",shmp[1], shmp[2]);
char *arg_vec[]={"./test", shmp[1], shmp[2], NULL};
I leave it for you to ensure proper lengths and adapt in case you need larger numbers.
Upvotes: 2