在C中,当作为参数传递给函数时,修改指向指针数组的指针的目标

时间:2011-09-10 20:22:34

标签: c pointers

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

#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;
}

3 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分: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);

并将其称为......

main()
{{1}}中的

。然后它将完美地运作:

  

broach @ roach-VirtualBox:〜$ ./test
  内功能:拉刀
  OK
  外部功能:拉刀

答案 2 :(得分: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);

并且main中的list_dir()调用变为:

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

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