执行strcpy时出现分段错误

执行strcpy时出现分段错误,c,malloc,strcpy,C,Malloc,Strcpy,我已经开始学习C语言,我一直在做一些小程序来学习。现在我正处在内存指针的关键时刻,我有一个快速的问题 据我所知,我在下面编写的程序将导航到/proc/sys/net/ipv4/conf/目录,并打印出其中列出的目录。我的目的是在函数getSysctlNames()中分配内存,然后在调用程序main()中取消分配内存。getSysctlNames()还应返回找到的目录名数。我已经了解到这不是最好的主意(在函数中分配,从调用者处取消分配),但我只是想胡闹和学习,而不是遵循一种模式。我的问题是,在运行

我已经开始学习C语言,我一直在做一些小程序来学习。现在我正处在内存指针的关键时刻,我有一个快速的问题

据我所知,我在下面编写的程序将导航到/proc/sys/net/ipv4/conf/目录,并打印出其中列出的目录。我的目的是在函数getSysctlNames()中分配内存,然后在调用程序main()中取消分配内存。getSysctlNames()还应返回找到的目录名数。我已经了解到这不是最好的主意(在函数中分配,从调用者处取消分配),但我只是想胡闹和学习,而不是遵循一种模式。我的问题是,在运行strcpy函数时,我在第55行获得了一个分段错误。我不确定我做错了什么。任何帮助都将不胜感激

int getSysctlNames(char** namesPointer);

int main(int argc, char **argv) {
    char** namesPointer;
    int numberOfNames = getSysctlNames(namesPointer);
    printf("Number of files: %i\n", numberOfNames);
    int i = 0;
    for (i = 0; i <= numberOfNames; i++) {
        printf("%s\n", namesPointer[i]);
        free(namesPointer[i]);

    }
    free(namesPointer);
    return 0;
}

int getSysctlNames(char** namesPointer) {
    int numberOfNames = 0;
    DIR *directory = opendir("/proc/sys/net/ipv4/conf/");
    if (directory) {
        struct dirent *directoryEntry;
        while ((directoryEntry = readdir(directory)) != NULL) {
            if (strcmp(directoryEntry->d_name, ".") != 0 &&
                strcmp(directoryEntry->d_name, "..") != 0) {
                numberOfNames++;
            }
        }
        closedir(directory);
    } else {
        return -1;
    }
    if (numberOfNames == 0) return 0;
    namesPointer = (char**) malloc(numberOfNames * sizeof(char*));
    if (namesPointer == NULL) {
        return -1;
    }
    directory = opendir("/proc/sys/net/ipv4/conf/");
    if (directory) {
        struct dirent *directoryEntry;
        int i = 0;
        while ((directoryEntry = readdir(directory)) != NULL) {
            if (strcmp(directoryEntry->d_name, ".") != 0 &&
                strcmp(directoryEntry->d_name, "..") != 0) {
                namesPointer[i] = malloc((strlen(directoryEntry->d_name) + 1) * sizeof(char));
                if (namesPointer[i] = NULL) {
                    int j = i - 1;
                    while (j >= 0) {
                        free(namesPointer[j]);
                        j--;
                    }
                    free(namesPointer);
                    return 0;
                }
                printf("%s\n", directoryEntry->d_name);
                strcpy(namesPointer[i], directoryEntry->d_name);
                printf("Got to 2\n");
                i++;
            }
        }
        closedir(directory);
        return numberOfNames;
    }
    free(namesPointer);
    return -1;
}
int getSysctlNames(char**namesPointer);
int main(int argc,字符**argv){
字符**名称指针;
int numberOfNames=getSysctlNames(namesPointer);
printf(“文件数:%i\n”,numberOfNames);
int i=0;
对于(i=0;i d_name,“.”!=0&&
strcmp(directoryEntry->d_name,“..”!=0){
numberOfNames++;
}
}
closedir(目录);
}否则{
返回-1;
}
如果(numberOfNames==0)返回0;
namesPointer=(char**)malloc(numberOfNames*sizeof(char*);
if(namesPointer==NULL){
返回-1;
}
directory=opendir(“/proc/sys/net/ipv4/conf/”);
如果(目录){
struct dirent*directoryEntry;
int i=0;
而((directoryEntry=readdir(directory))!=NULL){
如果(strcmp(directoryEntry->d_name,“.”)=0&&
strcmp(directoryEntry->d_name,“..”!=0){
namesPointer[i]=malloc((strlen(directoryEntry->d_name)+1)*sizeof(char));
if(namesPointer[i]=NULL){
int j=i-1;
而(j>=0){
自由(名称指针[j]);
j--;
}
自由(名称指针);
返回0;
}
printf(“%s\n”,directoryEntry->d_name);
strcpy(namesPointer[i],directoryEntry->d_name);
printf(“到达2\n”);
i++;
}
}
closedir(目录);
返回numberOfNames;
}
自由(名称指针);
返回-1;
}

分配内存,然后用NULL覆盖指针值:

namesPointer[i] = malloc((strlen(directoryEntry->d_name) + 1) * sizeof(char));
if (namesPointer[i] = NULL) {...
应该是

if (namesPointer[i] == NULL)


我得到了
intnumberofnames=getSysctlNames(namesPointer)。。当您将未初始化的变量传递给函数时,此行是错误的(这会导致未定义的行为)。也许您缺少C使用按值传递的功能—函数接收其参数的副本。记住这一点,检查代码的其余部分,如果(namesPointer[i]=NULL)
也是一个问题,那么显然需要重新设计函数调用
;如果您使用现代编译器并启用警告,那么编译器会为您指出这两个问题,即使使用现有最差的编译器,
strcpy(&namesPointer[i],
也会给出一条消息,告诉您存在问题。我猜您要么根本没有读取编译器输出,要么忽略它
(名称指针[i]=NULL)
是问题所在。在函数中传递未初始化的变量不是问题,而是可能导致问题的草率编程。如果计划在
main
中使用
namePointer
,并且没有从函数返回指向它的指针,则需要
char*namePointer;
并且调用是
int numberOfNames=getSysctlNames(&namesPointer);
(否则,该函数只是对指向类型的指针的副本进行操作。)您也可以使用相同的调用保留指向类型的指针,但您的声明将要求您成为三星级程序员(而不是补足语)谢谢。疲劳的眼睛似乎是造成这种情况的原因,我错过了一些人会编写
if(NULL==ptr)
来依靠编译器来选择这种错误的额外等号,但我不喜欢这样。我觉得这很难看。此外,现代编译器也警告过这种问题。
if (!namesPointer[i])