私の関数には、とりわけ、引数を持つコマンドを構成する単語へのポインターの NULL 終了配列を含む構造体が渡されています。
引数のリストでグロブ一致を実行して、それらをファイルの完全なリストに展開し、渡された引数配列を新しい展開された配列に置き換えたいと考えています。
グロビングは正常に機能しています。つまり、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);
}
編集 1: また、プログラムを cmd->argv[0] としてそこに戻す必要があることに気付きました
編集 2: calloc への呼び出しを追加しました
編集 3: Alok からのヒントを使用してメモリ管理を編集します
編集 4: Alok からのその他のヒント
編集 5:ほとんど動作しています..コマンド構造体を解放するときにアプリのセグメンテーション違反
最後に:終端のNULLが欠けていたようですので、次の行を追加してください:
cmd->argv[g.gl_pathc + g.gl_offs] = 0;
それを機能させるように見えました。