user13851309
user13851309

Reputation: 79

Passing by reference to an char array

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

Answers (1)

Gerhardh
Gerhardh

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

Related Questions