[英]Segmentation fault occured on passing a pointer to a char array into a function
這段代碼運行良好,直到我對其進行了修改。
int main(int argc, char** argv)
{
char command[1024];
gets(command);
char *delim = " \t\f";
char **tokens;
int i=0;
/* Extracting tokens from command string */
for(tokens[i] = strtok(command, delim); tokens[i] != NULL; tokens[i] = strtok(NULL, delim))
{
i++;
}
return 0;
}
這是由於分段錯誤而崩潰的代碼for(tokens[i] = strtok(command, delim); tokens[i] != NULL; tokens[i] = strtok(NULL, delim))
代碼 :
void commandProcess(char command[])
{
char *delim = " \t\f";
char **tokens;
int i=0;
/* Extracting tokens from command string */
for(tokens[i] = strtok(command, delim); tokens[i] != NULL; tokens[i] = strtok(NULL, delim))
{
i++;
}
}
int main(int argc, char** argv)
{
char command[1024];
gets(command);
process(command);
return 0;
}
我知道char command[]
會衰減到指針鏈接 ,並且strtok()會修改其第一個參數,在我的情況下,這可能是未定義的行為。 鏈接
因此,有人可以為我提供其他方法,以便我可以使用相同的函數簽名進行工作,並且仍然可以避免該問題嗎?
這似乎是一個小問題,但我無法解決。 :\\我什至嘗試過
void commandProcess(char command1[])
{
char command[1024];
int length = strlen(command1);
strncat(command, command1, length);
command[length] = '\0';
char *delim = " \t\f";
char **tokens;
int i=0;
/* Extracting tokens from command string */
for(tokens[i] = strtok(temp_command, delim); tokens[i] != NULL; tokens[i] = strtok(NULL, delim))
{
i++;
}
但隨后再次崩潰
for(tokens[i] = strtok(temp_command, delim); tokens[i] != NULL; tokens[i] = strtok(NULL, delim))
我認為delim
& tokens
不是罪魁禍首,因為沒有commandProcess()的程序可以很好地處理它們。
您寫入tokens[i]
,但是tokens
從未初始化。 取消引用未初始化的指針會調用未定義的行為 。
這意味着代碼的行為是不可預測的。 它可能會崩潰,可能會顯示奇怪的結果,或者看起來似乎可以正常工作。 同樣,進行看似無關的代碼更改可能會更改未定義行為的顯示方式。 這就是您的情況。
要解決此問題,您需要為tokens
分配空間。 在這種情況下,最簡單的方法是制作一個固定大小的指針數組:
char *tokens[1024];
您還可以malloc
內存,以便在堆棧上沒有大數組:
char **tokens = malloc(sizeof(char *) * 1024);
由於command
的長度為1024,因此令牌的數量不應更大。
正如其他評論和答案所指出的那樣,您需要為收集的令牌指針分配空間。
這是一個固定版本,它也使用fgets()
代替過時和危險的gets()
。 通常,不幸的是, fgets
有點麻煩,因為它將后綴\\n
留在緩沖區中。 然而,在這里,這很簡單,因為我們可以簡單地在delim
變量中添加'\\n'
來告訴strtok
分割什么。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXTOKS 100
void commandProcess(char command[])
{
char *delim = " \t\f\r\n";
char *tokens[MAXTOKS+1];
int i=0;
/* Extracting tokens from command string */
for(tokens[i] = strtok(command, delim); tokens[i] != NULL; tokens[i] = strtok(NULL, delim))
{
i++;
if(i > MAXTOKS)
{
fprintf(stderr, "too many tokens\n");
exit(1);
}
}
for(i = 0; tokens[i] != NULL; i++) printf("%d: \"%s\"\n", i, tokens[i]);
}
int main(int argc, char** argv)
{
char command[1024];
fgets(command, sizeof(command), stdin);
commandProcess(command);
return 0;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.