I simplified my code as much as possible:
#define MAX_BUF 4096
#define MAX_ARGS 200
int main() {
char **argv;
argv = malloc(sizeof(char*)*MAX_ARGS);
get_command(argv);
printf("arg0:%s\n", argv[0]);
cd(argv, NULL);
printf("arg2:%s\n", argv[0]);
}
void cd(char *argv[], char *old_pwd) {
char cwd[MAX_BUF];
printf("arg1:%s\n", argv[0]);
}
void get_command(char *argv[]) {
char input[MAX_BUF];
fgets(input, sizeof(input), stdin);
argv[0] = strtok(input, " ");
argv[1] = strtok(NULL, " ");
}
get_command reads the input of the user, let’s say it’s aa bb, it would then save aa to argv[0] and bb to argv[1]. Let’s note that argv is an array whose memory has been allocated dynamically inside main. Then, I pass argv to cd, but the elements of argv seem to change? The only thing I did there is declare a new string, and if I remove this declaration argv doesn’t change and it works correctly. So my guess is that what I am doing is somehow undefined behavior, but I don’t get how.
Thank you in advance!
>Solution :
get_command sets argv[0] and argv[1] to point to places within input. But, in the C model of computing, input ceases to exist when get_command returns, meaning the memory used for it is released and may be reused for other purposes.
Then the pointers in argv[0] and argv[1] become invalid, and the contents of the memory they pointed to may change, which likely happens when cd executes.
get_command should use malloc to allocate memory for the command or its parts. For good form, program should also free that memory when it is done using it.