2011-09-10 62 views
1

我想要一个返回给定目录的内容的函数。为此,我从dirent.h使用scandir。下面的代码成功编译(gcc -Wall test.c),但最后一个printf导致分段错误。这意味着在函数后面的“eps”结构(指向指向结构的指针数组的指针)仍然是空的:我该如何解决这个问题?在C中,当作为参数传递给函数时,修改指向指向数组的指针的目标

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

static int myselector(const struct dirent * dir_entry) 
{ 
    char * pch = strstr(dir_entry->d_name, "."); 
    return pch == NULL ? 1 : 0; 
} 

int list_dir(char * dirname, struct dirent ** eps) 
{ 
    int nbfiles = scandir(dirname, &eps, myselector, alphasort); 
    if(nbfiles > 0) 
    { 
    printf("inside function: %s\n", eps[0]->d_name); 
    return 1; 
    } 
    else 
    return 0; 
} 

int main(int argc, char *argv[]) 
{ 
    int status = 0; 
    struct dirent ** eps = NULL; 
    status = list_dir("/home", eps); 
    if (status) 
    { 
    puts("ok"); 
    printf("outside function: %s\n", eps[0]->d_name); 
    } 
    return EXIT_SUCCESS; 
} 

回答

1

因为你的指针发生了变化,你在main()寻找错误的事情:)

你传递一个指针的指针的指针scandir()。它正在改变一个指针指向的指针(我知道,这伤害了阅读...)。

因为你在你的函数中调用scandir()&eps,你会在函数外面失去这种改变。您的功能中eps的值已更改。

为了更好地理解这一点,在当前的功能包裹scandir()电话与printf()报表显示你什么包含在eps值:

... 
printf("%p\n", eps); 
int nbfiles = scandir(dirname, &eps, myselector, alphasort); 
printf("%p\n", eps); 
... 

为了解决这个问题改变你的函数:

int list_dir(char * dirname, struct dirent *** eps) 
{ 
    int nbfiles = scandir(dirname, eps, myselector, alphasort); 
    if(nbfiles != -1) 
    { 
    printf("inside function: %s\n", (*eps)[0]->d_name); 
    return 1; 
    } 
    else 
    return 0; 
} 

并称之为...

status = list_dir("/home", &eps); 

in main()。然后,它会很好地工作:

拉@蟑螂VirtualBox的:〜$ ./test
内部功能:戳破
确定
外功能:戳破

+0

谢谢,在典型的“指向指针...”的例子中有明确的答案......我需要将它刻在我的头上! – tflutre

1

您似乎没有覆盖scandir返回0即空目录的情况。 -1的返回值仅适用于错误。

+0

是的,我对这个简短的例子有点快,现在已经修复了。 – tflutre

+0

这是否修复了段错误? –

+0

不可以。段错误并不是由于输入目录可能为空,而是因为“eps”结构在我的“listd_dir”函数中填充,然后在函数完成后清空。我不知道如何防止这种情况。 – tflutre

1

制作list_dir采取struct dirent ***代替struct dirent **,在scandir()调用中除掉&运算符,并将其添加到main的list_dir()调用中。 list_dir的第一线()成为:

int list_dir(char * dirname, struct dirent *** eps) 
{ 
    int nbfiles = scandir(dirname, eps, myselector, alphasort); 

和在主的list_dir()调用变为:

status = list_dir("/home", &eps); 

这样list_dir()可以让SCANDIR()修改从主eps()通过它的地址,而不是修改参数,在栈上传递给list_dir()。

+0

完美,谢谢! (抱歉不要选择你的答案,Brian Roach从几分钟开始就更快;) – tflutre

相关问题