将 argv 复制到另一个变量以更改它而不更改原始变量
Copy argv to another variable to change it without change the original
我的程序有可变数量的参数,我需要用新路径创建一个 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
Edit2:我正在做 find
的一个版本,因此 strcat 将向当前目录添加一个要查看的文件夹。
这是目录的初始化:
char *directory = strcat(argv[1],"/");
显示的代码未NULL
-终止目标指针数组arg_exec
。
为此再分配一个元素,然后将其明确设置为 NULL
。
此外,代码对 arg_exe
的元素进行的第二次赋值会覆盖第一次的结果,导致内存泄漏,因为 strdup()
分配的内存地址丢失了。
假设 argv
通过 main()
传入,那么这一行
char *directory = strcat(argv[1],"/");
尝试将 "/"
连接到 argv[1]
指向的内容,并由此写入超出 argv[1]
的范围,并通过这样做调用未定义的行为。从那时起,任何事情都可能发生,从崩溃到似乎可以工作。
顺便说一句;请注意 directory
只是指向 char
的 指针 ,因此它不提供任何内存来存储任何类似 "string" 的值。
你可能想要什么而不是
char *directory = strcat(argv[1],"/");
...
arg_exec[1] = strcat(directory , dir_info->d_name);
是这样的(这假设 argv[1]
持有任何 "base"-目录的名称并且 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);
您没有说明 directory
是如何设置的。我怀疑它类似于
char *directory = argv[1];
在这种情况下,strcat 将修改 directory
指向的位置,从而修改 argv。
char *directory = strcat(argv[1],"/");
尝试修改 argv[1]
超出其分配,即 UB。 .
修改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()
我的程序有可变数量的参数,我需要用新路径创建一个 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
Edit2:我正在做 find
的一个版本,因此 strcat 将向当前目录添加一个要查看的文件夹。
这是目录的初始化:
char *directory = strcat(argv[1],"/");
显示的代码未NULL
-终止目标指针数组arg_exec
。
为此再分配一个元素,然后将其明确设置为 NULL
。
此外,代码对 arg_exe
的元素进行的第二次赋值会覆盖第一次的结果,导致内存泄漏,因为 strdup()
分配的内存地址丢失了。
假设 argv
通过 main()
传入,那么这一行
char *directory = strcat(argv[1],"/");
尝试将 "/"
连接到 argv[1]
指向的内容,并由此写入超出 argv[1]
的范围,并通过这样做调用未定义的行为。从那时起,任何事情都可能发生,从崩溃到似乎可以工作。
顺便说一句;请注意 directory
只是指向 char
的 指针 ,因此它不提供任何内存来存储任何类似 "string" 的值。
你可能想要什么而不是
char *directory = strcat(argv[1],"/");
...
arg_exec[1] = strcat(directory , dir_info->d_name);
是这样的(这假设 argv[1]
持有任何 "base"-目录的名称并且 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);
您没有说明 directory
是如何设置的。我怀疑它类似于
char *directory = argv[1];
在这种情况下,strcat 将修改 directory
指向的位置,从而修改 argv。
char *directory = strcat(argv[1],"/");
尝试修改 argv[1]
超出其分配,即 UB。
修改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()