Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/72.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
访问由C中的函数修改的字符串数组时出现分段错误_C_Arrays - Fatal编程技术网

访问由C中的函数修改的字符串数组时出现分段错误

访问由C中的函数修改的字符串数组时出现分段错误,c,arrays,C,Arrays,在main中,我定义了一个指向文件名字符串数组(有待确定)的指针: char**commands=NULL 然后调用一个函数,该函数使用getopt()基于argc和argv填充数组。在我从函数返回之前,我打印数组中的文件列表,它工作正常 回到main中,我试图打印相同的列表(作为确认),但我得到了一个分段错误,我不知道如何修复。我在下面包含了我的代码 有人能帮我理解为什么我的main中的命令无法访问文件列表吗 干杯, 小睡 以下是构建文件名列表的函数: int getInput (int ar

在main中,我定义了一个指向文件名字符串数组(有待确定)的指针:
char**commands=NULL
然后调用一个函数,该函数使用
getopt()
基于
argc
argv
填充数组。在我从函数返回之前,我打印数组中的文件列表,它工作正常

回到main中,我试图打印相同的列表(作为确认),但我得到了一个分段错误,我不知道如何修复。我在下面包含了我的代码

有人能帮我理解为什么我的main中的
命令
无法访问文件列表吗

干杯,
小睡

以下是构建文件名列表的函数:

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-getInput(int-argc,char**argv,const-char*选项列表,int*number,int*showEnds,char**命令,int*numberCommands){
字符c;
opterr=0;//关闭自动错误消息。
while((c=getopt(argc,argv,optionList))!=-1){
开关(c){
案例“n”:
*数字=真;
打破
案例“E”:
*showEnds=TRUE;
打破
案例“?”:
printf(“使用的开关无效\%c\”\n),optopt);
返回退出失败;
打破
违约:
printf(“发生输入错误”);
返回退出失败;
}
}
printf(“optind=%d,%d\n”,optind,argc);
commands=malloc(sizeof(char*)*(argc-1));
如果(选项D对于(inti=1;i您正在传递双指针的副本

char **commands;
当你为它
malloc()
内存时,它不会更新主函数中的指针,只更新双指针的本地副本。因此,你试图在主函数中使用空指针。你可以将指针传递给双指针(即,函数将采用三重指针),那么您的代码就可以工作了

您需要在函数中取消对三重指针的引用,如下所示:

*commands = malloc(sizeof(char*) * (argc-1));
或者,在函数中创建一个新的双指针,完成工作(使函数中的代码大致保持原样),然后在返回之前,将内存分配回从main传入的指针:

*commands = local_commands;
在该功能中:

int getInput (/* ... */, char **commands, int *numberCommands) {

    /* ... */
    commands = malloc(sizeof(char*) * (argc-1));
}
int getInput (/* ... */, char ***commands, int *numberCommands) {

    /* ... */
    *commands = malloc(sizeof(char*) * (argc-1));
}
您接受指向char参数的指针(按值)。查看调用站点,我们可以看到该值始终为
(char**)NULL
。该参数是函数中的一个局部变量。即使您更改了它,即使调用方恰好有一个同名变量,您也不会更改调用方的副本

如果要更改调用方的
命令副本
,则需要将该变量的地址传递给函数:

int getInput (/* ... */, char **commands, int *numberCommands) {

    /* ... */
    commands = malloc(sizeof(char*) * (argc-1));
}
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);
    }
}

请注意,
命令
数字命令
是两个输出参数-也就是说,它们是函数应该更改局部变量的参数-因此您使用
&
将指针传递给这两个参数。

谢谢!!我将另一个标记为我的答案,因为建议在局部重命名变量,从而使其更易于阅读和理解。很好的调用,使用局部变量来澄清发生了什么!谢谢!!