【问题标题】:Segfault/incompatible type error when attempting to create an array of directory structures尝试创建目录结构数组时出现段错误/不兼容类型错误
【发布时间】:2019-05-07 08:55:40
【问题描述】:

我正在使用 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))(来自有关该主题的多个帖子的逐字记录)会出现这种不兼容的类型错误。如果使用不合适,为什么会出现段错误?

【问题讨论】:

  • 你是如何编译这段代码的?你用什么命令?
  • 你是用 C++ 编译器编译这个吗?符合标准的 C 编译器不应抱怨将 malloc() 的返回值分配给任何对象指针类型的对象。
  • @xing 不错,但不能解决分配错误。新错误是a.out(3319,0x7fff74201300) malloc: *** error for object 0x7fb772003218: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug ...Abort trap: 6

标签: c malloc dirent.h


【解决方案1】:

运行上述代码会导致分段错误:11。

这可能是因为

    printf(d_array[n]->d_name);

    free(d_array[n]);

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

也可能是因为

free(d_array);

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

我不明白为什么d_array[n] = malloc(sizeof(struct dirent)), 这是关于这个主题的多个帖子的逐字记录,有这个 不兼容的类型错误。

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

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

    *d_array[i] = *dir;

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

【讨论】:

  • 感谢您的回答。我修复了索引问题,但不幸的是,它并没有解决我的分配问题,即使强制编译器使用 c。我现在收到以下错误:a.out(3319,0x7fff74201300) malloc: *** error for object 0x7fb772003218: pointer being freed was not allocated *** set a breakpoint in malloc_error_break to debug ...Abort trap: 6
  • @Hierophect,索引问题只是我指出的几个问题之一。其他一些涉及确实不应该尝试释放的指针。但是,我可能还应该提及一两件事。
  • 此外,虽然我现在可以强制程序在 C 中编译,但理想情况下,我希望将此代码包含在 C++ 程序中(由于其他库的要求)。有没有其他方法可以避免这个错误?
  • @Hierophect 这段代码的整个结构被破坏了。如果您使用 C++,您应该只将条目名称读入 vector&lt;string&gt; 而忘记复制 struct dirents。
  • readdir 手册页明确指出您不能像这样复制 struct dirents:“POSIX.1 明确指出 [d_name] 不应用作左值。[ ...](在某些系统上,该字段定义为char d_name[1]!)"
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-20
  • 2021-05-18
  • 1970-01-01
  • 2021-07-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多