2017-04-07 52 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

是的,這也是一個問題。更正它 –

相關問題