Проблема в том, что вы выделяете массив char * внутри parse_command
, но указатель на этот массив никогда не выходит из функции. Таким образом, exec_command
получает значение указателя мусора. Причина в том, что при вызове parse_command(line, command)
вы передаете копию текущего значения указателя command
, который затем перезаписывается внутри функции - но это не влияет на исходное значение !
Для этого либо вам нужно передать указатель на указатель, который вы хотите обновить, либо вам нужно вернуть указатель на выделенный массив из parse_command
. Помимо того, что char***
выглядит некрасиво (по крайней мере, для меня), последний подход более прост и удобен для чтения:
int main()
{
char** command = NULL;
while (true)
{
fgets(line, MAX_COMMAND_LEN, stdin);
command = parse_command(line);
exec_command(command);
}
}
char** parse_command(char* line)
{
char** command = NULL;
int n_args = 0, i = 0;
while (line[i] != '\n')
{
if (isspace(line[i++]))
n_args++;
}
command = (char**) malloc ((n_args + 1) * sizeof(char*));
i = 0;
line = strtok(line," \n");
while (line != NULL)
{
command[i] = (char *) malloc ( (strlen(line)+1) * sizeof(char) );
strcpy(command[i++], line);
line = strtok(NULL, " \n");
}
command[i] = NULL;
return command;
}
Примечания:
- в исходном
parse_command
, вы выделяете память для command
в цикле, который не нужен и просто создает утечки памяти. Достаточно выделить память один раз. Я предполагаю, что вы хотите, чтобы command
содержал n_args + 1
указателей, поэтому я изменил код соответствующим образом.
- в последнем цикле
while
, равном parse_command
, вы неправильно увеличиваете i
дважды, что также приводит к неопределенному поведению, т. Е. Возможной ошибке сегментации. Я исправил это здесь.