在我的主要部分中,我定义了一个指向文件名字符串数组的指针(需要确定):
char **commands = NULL;
然后,我调用一个函数,该函数根据argc
& argv
使用getopt()
。在我从函数返回之前,我打印了数组中的文件列表,它工作正常。
回到我的主要部分,我尝试打印相同的列表(作为确认),但是我得到了一个分段错误,我无法弄清楚如何修复。我在下面提供了我的代码。
有人可以帮我理解为什么我的主要commands
无法访问文件列表。
干杯,
N ap个
以下是构建文件名列表的函数:
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);
}
答案 0 :(得分:1)
你传递了双指针的副本
char **commands;
进入功能。当你malloc()
内存时,它不会更新主函数中的指针,只会更新双指针的本地副本。因此,您尝试在main中使用NULL指针。你可以改为传递一个指向双指针的指针(即函数将采用三指针),那么你的代码就可以了。
您需要取消引用函数内部的三重指针,如下所示:
*commands = malloc(sizeof(char*) * (argc-1));
或者,在你的函数中创建一个新的双指针,完成你的工作(将函数中的代码保持原样)并在返回之前,将内存分配回从main传入的指针:
*commands = local_commands;
答案 1 :(得分:0)
在此功能中:
int getInput (/* ... */, char **commands, int *numberCommands) {
/* ... */
commands = malloc(sizeof(char*) * (argc-1));
}
您接受按值指向指针指向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
是两个 out-parameters - 也就是说,它们是函数应该更改本地变量的参数 - 所以你'重新使用&
将指针传递给它们。