所以我想決議一個類似于 shell 的命令并將其存盤在一個 char** 上,以便將它作為引數傳遞給 execv 系統呼叫。在下面的函式中,決議和存盤作業正常。
char ** input_delimit(char *command){ // 19
char **retval; // 20
const char space[2]=" "; // 21
int i=0; // 22
retval=(char**)malloc(sizeof(char*)); // 23
retval[i]=(char*)malloc(sizeof(char)); // 24
retval[i]=strtok(command,space); // 25
while(retval[i]!=NULL){ // 26
i ; // 27
retval[i]=(char*)malloc(sizeof(char)); // 28
retval[i]=strtok(NULL,space); // 29
} // 30
return retval; // 31
} // 32
當我使用 Valgrind 運行我的代碼時,我收到以下錯誤訊息(盡管它正確地完成了我想要它做的事情)。為什么會這樣?
==824== Invalid write of size 8
==824== at 0x109410: input_delimit (shell.c:28)
==824== by 0x109493: execute_command (shell.c:35)
==824== by 0x109600: main (shell.c:64)
==824== Address 0x4a489d8 is 0 bytes after a block of size 8 alloc'd
==824== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==824== by 0x1093A7: input_delimit (shell.c:23)
==824== by 0x109493: execute_command (shell.c:35)
==824== by 0x109600: main (shell.c:64)
==824==
==824== Invalid write of size 8
==824== at 0x109439: input_delimit (shell.c:29)
==824== by 0x109493: execute_command (shell.c:35)
==824== by 0x109600: main (shell.c:64)
==824== Address 0x4a489d8 is 0 bytes after a block of size 8 alloc'd
==824== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==824== by 0x1093A7: input_delimit (shell.c:23)
==824== by 0x109493: execute_command (shell.c:35)
==824== by 0x109600: main (shell.c:64)
==824==
==824== Invalid read of size 8
==824== at 0x109450: input_delimit (shell.c:26)
==824== by 0x109493: execute_command (shell.c:35)
==824== by 0x109600: main (shell.c:64)
==824== Address 0x4a489d8 is 0 bytes after a block of size 8 alloc'd
==824== at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==824== by 0x1093A7: input_delimit (shell.c:23)
==824== by 0x109493: execute_command (shell.c:35)
==824== by 0x109600: main (shell.c:64)
uj5u.com熱心網友回復:
您僅為一個指標動態分配記憶體
retval=(char**)malloc(sizeof(char*));
所以這個回圈
while(retval[i]!=NULL){
i ;
retval[i]=(char*)malloc(sizeof(char));
retval[i]=strtok(NULL,space);
}
呼叫未定義的行為。
此外,這些陳述
retval[i]=(char*)malloc(sizeof(char));
retval[i]=strtok(command,space)
產生記憶體泄漏,因為記憶體已分配且其地址已分配給指標retval[i],并且在下一條陳述句中重新分配了指標。所以分配的記憶體地址就丟失了。
您需要在while回圈中使用realloc指標。retval
uj5u.com熱心網友回復:
這個 ...
retval=(char**)malloc(sizeof(char*));
...分配足夠的空間來存盤一個 char *。
這個 ...
retval[i]=(char*)malloc(sizeof(char));
... 為 one 分配空間char并將指向它的指標分配給retval[i]. 當您用不同的指標覆寫該指標時,該空間隨后會泄漏:
retval[i]=strtok(command,space);
但現在主要問題來了。 retval指向空間足夠大的一個char *。因此,這個的每一次迭代......
i ; retval[i]=(char*)malloc(sizeof(char)); retval[i]=strtok(NULL,space);
...超出分配空間的界限(更不用說分配并立即泄漏另一個塊)。我希望 Valgrind 會注意到,并發出您所描述的這種診斷。
建議:
首先為至少兩個塊分配空間,因為任何有效命令都至少需要這些空間。
跳過那些單一
char分配。它們不僅沒有任何用處,而且實際上是有害的。當您在未到達命令末尾的情況下填滿分配的空間時,請使用
realloc()來獲取更多單詞的空間。這意味著您必須跟蹤您已經分配了多少空間。例子:char *temp = realloc(retval, new_capacity * sizeof(*retval)); if (!temp) { // handle allocation failure ... } else { retval = temp; }
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/513300.html
上一篇:如何獲取C中指標指向的值的地址?
