Моя функция передается структурой, содержащей, среди прочего, NULL завершенный массив указателей на слова, составляющие команду с аргументами.Как переписать массив указателей на символы с большим списком указателей на символы?
Я выполняю сопоставление glob в списке аргументов, чтобы развернуть их в полный список файлов, а затем я хочу заменить переданный массив аргументов новым расширенным.
Глобус работает нормально, то есть g.gl_pathv заполняется списком ожидаемых файлов. Однако мне трудно скопировать этот массив в структуру, которую я получил.
#include <glob.h>
struct command {
char **argv;
// other fields...
}
void myFunction(struct command * cmd)
{
char **p = cmd->argv;
char* program = *p++; // save the program name (e.g 'ls', and increment to the first argument
glob_t g;
memset(&g, 0, sizeof(g));
g.gl_offs = 1;
int res = glob(*p++, GLOB_DOOFFS, NULL, &g);
glob_handle_res(res);
while (*p)
{
res = glob(*p, GLOB_DOOFFS | GLOB_APPEND, NULL, &g);
glob_handle_res(res);
}
if(g.gl_pathc <= 0)
{
globfree(&g);
}
cmd->argv = malloc((g.gl_pathc + g.gl_offs) * sizeof *cmd->argv);
if (cmd->argv == NULL) { sys_fatal_error("pattern_expand: malloc failed\n");}
// copy over the arguments
size_t i = g.gl_offs;
for (; i < g.gl_pathc + g.gl_offs; ++i)
cmd->argv[i] = strdup(g.gl_pathv[i]);
// insert the original program name
cmd->argv[0] = strdup(program);
** cmd->argv[g.gl_pathc + g.gl_offs] = 0; **
globfree(&g);
}
void
command_free(struct esh_command * cmd)
{
char ** p = cmd->argv;
while (*p) {
free(*p++); // Segfaults here, was it already freed?
}
free(cmd->argv);
free(cmd);
}
Edit 1: Кроме того, я понял, что нужно придерживаться программы обратно туда, как Cmd-> ARGV [0]
Edit 2: Добавлен вызов calloc
Редактировать 3: Изменить управление MEM с советами от Alok
Edit 4: Дополнительные советы от Alok
Edit 5: Почти работает .. приложение при освобождении ошибки сегментации команды-структуру
Наконец: Похоже, мне не хватало завершающего NULL, поэтому добавление строки:
cmd->argv[g.gl_pathc + g.gl_offs] = 0;
, похоже, запустил его.
Так оно работает сейчас? Если нет, то какая ошибка вы получаете? Также см. Мое последнее изменение в моем ответе. Вы выделяете пробел дважды для 'paths [0]', один раз с 'malloc', а затем снова с' strdup'. –
да, этот код был жестоким .. см. Последнее редактирование. он по-прежнему сбой при доступе к новому массиву. Возможно, символы \ 0 теряются при перетасовке? – Casey
В 'cmd-> argv [g.gl_pathc + g.gl_offs] = '\ 0';', '' \ 0'' эквивалентен '0', что эквивалентно здесь' NULL', поэтому вы должны используйте 'NULL' вместо' '\ 0''. –