[英]Segmentation Fault when accessing string array modified by a function in C
在我的主機中,我定義了一個指向文件名字符串數組(將要確定)的指針:
char **commands = NULL;
然后,我調用一個函數,該argv
使用getopt()
基於argc
和argv
填充數組。 從函數返回之前,我先打印數組中的文件列表,然后工作正常。
回到我的主文件夾中,我嘗試打印相同的列表(作為確認),但出現了細分錯誤,無法弄清楚該如何解決。 我在下面包含了我的代碼。
有人可以幫我理解為什么我主目錄中的commands
無法訪問文件列表的原因。
干杯,
小憩
這是構建文件名列表的函數:
int getInput (int argc, char **argv, const char *optionList, int *number, int *showEnds, char **commands, int *numberCommands) {
char c;
opterr = 0; // Turn off automatic error messages.
while ( (c = getopt(argc, argv, optionList)) != -1) {
switch (c) {
case 'n':
*number = TRUE;
break;
case 'E':
*showEnds = TRUE;
break;
case '?':
printf("Invalid switch used \"%c\"\n", optopt);
return EXIT_FAILURE;
break;
default:
printf("Input error occurred");
return EXIT_FAILURE;
}
}
printf("optind = %d,%d\n",optind, argc);
commands = malloc(sizeof(char*) * (argc-1));
if (optind < argc) {
*numberCommands = (argc - optind);
int ndx = 1;
while (optind < argc) {
int arraySize = (ndx+1)*sizeof(char*);
commands = realloc (commands,arraySize);
if (commands == NULL) {
fprintf(stderr,"Realloc unsuccessful");
exit(EXIT_FAILURE);
}
int stringSize = strlen(argv[optind])+1;
commands[ndx] = malloc(stringSize);
if(commands[ndx]==NULL){
fprintf(stderr,"Malloc unsuccessful");
exit(EXIT_FAILURE);
}
strcpy(commands[ndx],argv[optind]);
ndx++;
optind++;
}
printf ("Done With Input\n");
for (int i=1; i<=*numberCommands; i++) {
printf ("%s\n",commands[i]);
}
}
return EXIT_SUCCESS;
}
這是我的主要內容:
int main(int argc, char **argv) {
FILE *myInput;
FILE *myOutput;
int result;
const char availOptions[] = "nE";
// Option flags
int number = FALSE; // (Option n) number all output lines
int showEnds = FALSE; // (Option E) Show Ends
char **commands = NULL;
int numberCommands = 0;
// Set default to stdin/stdout.
myInput = stdin;
myOutput = stdout;
if (argc > 1) {
result = getInput(argc,argv, availOptions, &number, &showEnds, commands, &numberCommands);
if (result != EXIT_SUCCESS) {
exit(EXIT_FAILURE);
}
}
printf ("Number of files = %d\n", numberCommands);
for (int i=1; i<=numberCommands; i++) {
printf ("%s\n",commands[i]);
}
echoInput(myInput, myOutput);
}
您正在傳遞雙指針的副本
char **commands;
進入功能。 當您為它malloc()
內存時,它不會更新主函數中的指針,而只會更新雙指針的本地副本。 因此,您嘗試在main中引用NULL指針。 您可以改為將指針傳遞給雙指針(即該函數將使用三指針),然后您的代碼將起作用。
您將需要在函數內部取消引用三指針,如下所示:
*commands = malloc(sizeof(char*) * (argc-1));
或者,在函數內部創建一個新的雙指針,進行工作(將代碼大致保留在函數中),然后再返回,將內存分配回從main傳遞的指針中:
*commands = local_commands;
在此功能中:
int getInput (/* ... */, char **commands, int *numberCommands) {
/* ... */
commands = malloc(sizeof(char*) * (argc-1));
}
您可以通過value接受一個指向char的指針參數。 查看呼叫站點,我們可以看到該值將始終為(char**)NULL
。 參數是函數內部的局部變量 。 即使您更改了它,並且即使調用者恰巧有一個具有相同名稱的變量,也永遠不會更改調用者的副本。
如果要更改調用方的commands
副本,則需要將該變量的地址傳遞給函數:
int getInput (/* ... */, char ***commands, int *numberCommands) {
/* ... */
*commands = malloc(sizeof(char*) * (argc-1));
}
現在,呼叫站點如下所示:
char **commands = NULL;
int numberCommands = 0;
/* ... */
if (argc > 1) {
result = getInput(/*...*/, &commands, &numberCommands);
if (result != EXIT_SUCCESS) {
exit(EXIT_FAILURE);
}
}
請注意, commands
和numberCommands
是兩個輸出參數 -也就是說,它們是函數應在其中更改局部變量的參數-因此,您使用&
傳遞指向兩者的指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.