2017-04-07 67 views
1

我的程序有一个可变数量的参数,我需要用新路径创建一个execv,所以我想在不更改的情况下更改其他变量的值argv[1]它,但它不会让我。将argv复制到另一个变量以更改它,而不更改原始

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:在阵列 EDIT2的末尾添加NULL:我做一个版本的find的,所以strcat的会添加到当前目录下的一个文件夹来看看。 这是目录中的初始化: char *directory = strcat(argv[1],"/");

+2

背后的想法是什么:'arg_exec [1] = strcat(directory,dir_info-> d_name);'?那么'directory'是如何定义和创建的呢? – alk

+0

我正在做一个'find'的版本,所以strcat会在当前目录中添加一个文件夹来查看 –

+0

引用“* Edit1 *”:你错过了调整要分配的数组元素的数量。 – alk

回答

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()

+0

在最佳情况下调用'free()'将永远不会执行... ;-)我会在它们之前添加一个'perror()'。 – alk

+1

@alk也许\t 修改'argv'是UB,也许不是。补充说明。回覆; 'perror()',OP有'printf(“错误正在处理%d \ n”,getpid());' – chux

+0

对我而言 –

2

代码如图偏出NULL -terminate目标指针数组arg_exec

为此,再分配一个元素,然后将其明确设置为NULL


另外,第二分配代码的功能,以arg_exe的元件覆盖所述第一的结果,引起了内存泄漏,作为地址到存储器由strdup()分配丢失。


假设argv被通过main()传递,那么这行

char *directory = strcat(argv[1],"/"); 

试图串连"/"超越的argv[1]界限argv[1]指向与该什么写并通过这样做调用未定义行为。从那时起,任何事情都可能发生,从碰撞到看似工作。

BTW;请注意,directory只是一个指针char,所以它不提供任何内存来存储任何类似“字符串”的值。

你可能要代替

char *directory = strcat(argv[1],"/"); 

... 

    arg_exec[1] = strcat(directory , dir_info->d_name); 

什么是这样的(假设argv[1]持有任何“基地” -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); 
+0

我不知道为什么,与realloc错误。另一个答案解决了我的问题,无论如何感谢 –

2

您不显示如何设置directory。我怀疑它的东西,像

char *directory = argv[1]; 

在这种情况下,strcat的将修改位置directory指向,因此ARGV。

+0

是的,这也是一个问题。更正它 –