argv
- это массив указателей char *
. Это означает, что argv
имеет место для значений argc
char *
. Если вы попытаетесь скопировать в него больше, чем столько char *
значений, вы получите переполнение.
Скорее всего, ваш glob
вызов приведет к более чем argc
элементам в поле gl_pathv
(т.е. gl_pathc > argc
). Это неопределенное поведение.
Это похоже на код ниже:
/* Wrong code */
#include <string.h>
int a[] = { 1, 2, 3 };
int b[] = { 1, 2, 3, 4 };
memcpy(a, b, sizeof b);
Решение: вы должны либо работать со структурой glob_t
напрямую, либо выделять новое пространство для копирования gl_pathv
в новый char **
:
char **paths = malloc(g.gl_pathc * sizeof *paths);
if (paths == NULL) { /* handle error */ }
for (size_t i=0; i < g.gl_pathc; ++i) {
/* The following just copies the pointer */
paths[i] = g.gl_pathv[i];
/* If you actually want to copy the string, then
you need to malloc again here.
Something like:
paths[i] = malloc(strlen(g.gl_pathv[i] + 1));
followed by strcpy.
*/
}
/* free all the allocated data when done */
Редактировать : после редактирования:
cmd->argv = calloc(g.gl_pathc, sizeof(char *) *g.gl_pathc);
это должно работать, но каждый из argv[1]
- argv[g.gl_pathc + g.gl_offs - 1]
- это char *
, который "принадлежит" struct glob
. Ваш memcpy
звонок только копирует указатели. Когда вы позже делаете globfree()
, эти указатели больше ничего не значат. Итак, вам нужно скопировать строки для вашего использования:
size_t i;
cmd->argv = malloc((g.gl_pathc+g.gl_offs) * sizeof *cmd->argv);
for (i=g.gl_offs; i < g.gl_pathc + g.gl_offs; ++i)
cmd->argv[i] = strdup(g.gl_pathv[i]);
Это гарантирует, что теперь у вас есть свои собственные частные копии строк. Обязательно освободите их (и argv
), как только вы закончите.
Есть несколько других проблем с вашим кодом.
- Вы делаете
*p++
, вы должны сделать p++
, так как вы не используете значение разыменования.
- Вы действительно должны проверить возвращаемое значение
glob
.
- Ваша переменная
paths
нуждается в g.gl_pathc + 1
элементах, а не g.gl_pathc
. (Точнее, вам нужно выделить g.gl_pathc + g.gl_offs
раз sizeof *paths
байт.)
- Ваш цикл
for
для копирования строк должен быть for (j=1; j < g.gl_pathc + g.gl_offs; ++j)
.
- Убедитесь, что оболочка не расширяет ваш шар. То есть звоните
./a.out '*'
вместо ./a.out *
.