Segfault/incompatible 尝试创建目录结构数组时出现类型错误

Segfault/incompatible type error when attempting to create an array of directory structures

我正在使用 dirent.h 库扫描一个目录以查找它包含的所有文件,并将指向结果对象的指针存储在一个数组中。我一直在关注 old SO question 描述结构指针在数组中的存储,但我 运行 在实施过程中遇到了问题。

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>

int main(int argc, char **argv) 
{
    DIR *d = NULL;
    struct dirent *dir = NULL;
    struct dirent *d_array[50]; //big overkill array to avoid realloc
    size_t n = 0; //number of items

    d = opendir("scandir"); //name of directory to search
    if(d)
    { 
        while((dir = readdir(d))!=NULL) {
            //d_array[n] = malloc(sizeof(struct dirent));
            d_array[n++] = dir;
        }
        closedir(d);
    }
    for(size_t i = 0;i<n;i++) {
        printf(d_array[n]->d_name);
        free(d_array[n]);
    }
    free(d_array);
    return 0;
}

运行 上面的代码导致分段错误:11。我认为这可能是因为我为结构正确分配了内存(如注释掉的 malloc 中所示),但包括它给出以下错误:

error: assigning to 'struct dirent *' from incompatible type
  'void *'

我不明白为什么 d_array[n] = malloc(sizeof(struct dirent)) 会出现这种类型不兼容的错误,它是关于此主题的多篇帖子的逐字记录。如果使用不当,为什么会出现段错误?

Running the above code results in a Segmentation fault: 11.

这可能是因为

    printf(d_array[n]->d_name);

    free(d_array[n]);

,因为n是目录项的个数,而d_array[n]是未初始化的。 (您的意思似乎是 d_array[i])另外请注意,您不应尝试释放 readdir() 返回的指针,因为它不属于您。该文档特别指出您不应尝试释放它。这可能适用于您只需将指针本身分配给数组的版本。

也可能是因为

free(d_array);

,因为d_array本身不是动态分配的。您可以合理地希望您的编译器会对此发出警告。我的有。

I don't understand why d_array[n] = malloc(sizeof(struct dirent)), which is verbatim from multiple posts about this topic, is having this incompatible type error.

那是因为您的编译器不符合规范。也许您使用的是 C++ 编译器而不是 C 编译器——它们不可互换。该语句是完全有效的 C,考虑到它出现在您的代码中的范围内的声明。

附录: 至于你实际应该做什么,如果你要为 d_array 的元素动态分配内存指向(你应该,如果你使用指针数组)那么你需要复制 指向struct dirent结构到分配的space,而不是将返回的指针直接分配给数组。那将是

    *d_array[i] = *dir;

正如 Paul Ogilvie 在现已删除的回答中首先指出的那样。