struct dirent ** foo到一个函数

时间:2016-01-14 21:41:27

标签: c function pointers struct

我试图用scandir初始化函数内部的结构。我想将目录中的所有文件存储到一个数组中并用它们做一些处理。

void main() {
    struct dirent **list;
    int n = read("/home/user", list);
    print(list, n);
    free(list);
}

int read(char *path, struct dirent **foo) {
    int n = scandir(path, &foo, 0, alphasort);
    return 0; 
}

void print(struct dirent **foo, int n) {
    int i = 0;
    for (i = 0; i < n; i++){
        struct dirent *entry;
        entry = nameList[i];
        printf("%s\n", entry->d_name);
        free(entry);
    }
}

为什么read(char*, struct dirent**)会导致segmentation fault? 当我补充它时它没有错误,我在这里有点迷失。

2 个答案:

答案 0 :(得分:2)

int scandir(const char *dirp, struct dirent ***namelist,
              int (*filter)(const struct dirent *),
              int (*compar)(const struct dirent **, const struct dirent **));

scandir将指针指向指针,但是在函数

int read(char *path, struct dirent **foo) {
    int n = scandir(path, &foo, 0, alphasort);
    return 0; 
}

您正在将本地指针的地址传递给指针。改为使用指针的地址:

int read(char *path, struct dirent ***foo) {
    int n = scandir(path, foo, 0, alphasort);
    return 0; 
}

void main() {
    struct dirent **list;
    int n = read("/home/user", &list);
    print(list, n);
    free(list);
}

此外:

scandir()函数返回所选目录条目的数量。出错时,返回-1,并设置errno以指示错误原因。

因此,如果您想要打印任何内容并在main中处理错误,则应更改读取功能:

int my_read(char *path, struct dirent ***foo) 
{
    return scandir(path, foo, 0, alphasort); 
}

在main()中:

    int n = read("/home/user", &list);
    if (n < 0)
    {
        perror("scandir failed");
        exit(EXIT_FAILURE);
    }

答案 1 :(得分:0)

您的代码存在一些问题:

  • read是C库定义和使用的POSIX函数的名称,为函数使用不同的名称。

  • 您修改了read函数中的参数foo,而不是list中值传递的局部变量main。您必须传递list的地址并将原型更改为int read_entries(const char *path, struct dirent ***foo)

  • 您应该从阅读功能中返回条目数。

  • free函数print中的条目:这是误导性的,你应该使用一个特定的函数来释放由scandir分配的结构和数组。

  • 原型void main()不正确。

以下是更正后的版本:

#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>

int read_entries(const char *path, struct dirent ***foo) {
    return scandir(path, foo, NULL, alphasort);
}

void print_entries(struct dirent **list, int n) {
    for (int i = 0; i < n; i++) {
        printf("%s\n", list[i]->d_name);
    }
}

void free_entries(struct dirent **list, int n) {
    for (int i = 0; i < n; i++) {
        free(list[i]);
    }
    free(list)
}

int main() {
    struct dirent **list;
    int n = read_entries("/home/user", &list);
    if (n < 0) {
        printf("cannot enumerate directory /home/user: %s\n",
               strerror(errno));
    } else {
        print_entries(list, n);
        free_entries(list, n);
    }
    return 0;
}