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!
CodePudding user response:
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.