我的程序有一个可变数量的args,我需要创建一个带有新路径的execv
,所以我想在不改变它的情况下在另一个变量中更改argv[1]
的值,但它不能让我。
char** arg_exec = malloc(argc * sizeof (char*));
int i;
for(i=0;i <= argc-1; i++)
arg_exec[i] = strdup(argv[i]);
arg_exec[argc] = NULL;
if( (pid = fork()) == 0){
arg_exec[1] = strcat(directory , dir_info->d_name); //some variables with the current path and a name
execv(arg_exec[0], arg_exec);
printf("Error in process %d\n", getpid());
return 1;
}
但在运行此行arg_exec[1] = strcat(directory , dir_info->d_name);
后,它会更改我的argv [1]值,并且我的程序失败..
它与execl
一起工作正常,因为它就像execl(argv[0],strcat(directory , dir_info->d_name), ..., NULL);
,但因为我有一个可变数量的参数来运行它,所以实现这种方式并不好。
Edit1:在数组末尾添加了NULL
编辑2:我正在做find
的版本,因此strcat会将当前目录添加到要查看的文件夹中。
这是目录的初始化:
char *directory = strcat(argv[1],"/");
答案 0 :(得分:2)
显示的代码未命中NULL
- 终止目标指针数组arg_exec
。
为此,请再分配一个元素,然后将其显式设置为NULL
。
此外,代码对arg_exe
的元素执行的第二项赋值会覆盖第一项结果,导致内存泄漏,因为strdup()
分配给内存的地址丢失。
假设argv
通过main()
传递,则此行
char *directory = strcat(argv[1],"/");
尝试将"/"
连接到argv[1]
所指向的内容,并将此写入超出argv[1]
的范围,并通过这样做来调用未定义的行为。从那时起,任何事情都会发生,从崩溃到看似工作。
顺便说一句;请注意directory
只是指针到char
,所以它不提供任何内存来存储任何&#34;字符串&#34;类似的值。
你可能想要什么而不是
char *directory = strcat(argv[1],"/");
...
arg_exec[1] = strcat(directory , dir_info->d_name);
是这样的(这假设argv[1]
包含任何&#34; base&#34; -directorie的名称,argv_exe
根据您的(更正的)代码进行分配和初始化:
{
void * tmp = realloc(arg_exec[1],
strlen(arg_exec[1]) + strlen("/") + strlen(dir_info->d_name) + 1);
if (NULL == tmp)
{
perror("realloc() failed");
exit(1);
}
arg_exec[1] = tmp;
}
strcat(arg_exec[1], "/");
strcat(arg_exec[1], dir_info->d_name);
答案 1 :(得分:2)
您没有显示directory
的设置方式。我怀疑它就像
char *directory = argv[1];
在这种情况下,strcat将修改directory
所指向的位置,从而修改argv。
答案 2 :(得分:2)
char *directory = strcat(argv[1],"/");
尝试修改argv[1]
超出其分配范围,即UB。 @alk
修改argv
本身可能是UB。 Is argv[n] writable?
所以为两者分配内存。
注意:char** arg_exec = malloc(argc * sizeof (char*));
不足,因为argv[argc]
必须是NULL
。需要1个。请注意,argc
未传递给execv()
。
步骤1.复制指针数组argv[]
char **argv_new;
size_t a_size = sizeof *argv_new * (argc + 1); // + 1 for the final NULL
argv_new = malloc(a_size);
memcpy(argv_new, argv, a_size);
步骤2.形成新的arg [1]
int size = 1 + snprintf(NULL, 0, "%s/%s", argv[1], dir_info->d_name);
argv_new[1] = malloc(size);
snprintf(argv_new[1], size, "%s/%s", argv[1], dir_info->d_name);
使用它
execv(arg_new[0], arg_new);
free(argv_new[1]);
free(argv_new);
待定:错误检查添加:argc > 1, malloc(), snprintf(), execv()