我需要分配内存的结构的dirent(Do I need to Allocate Memory for

2019-10-29 14:25发布

  • 平台:Windows XP服务包3
  • 编译:代码:: Blocks的12.11版

我目前正在写一个程序,将使用POSIX目录功能递归删除给出的目录。 但我有READDIR()和其对应的的dirent结构的问题。 我的readdir在阅读文档,对函数的多次调用将覆盖该函数返回的结构中保存的数据。 因此,我认为READDIR()必须allcoate memmory的结构本身,然后简单地重新分配指针地址到捕获它的返回值的结构。 我测试这个理论,我是正确的readdir()分配memmory为它的成员d_name。 我遇到的问题是,当readdir的目录流为空,则返回NULL指针,所以我用一个while循环与条件(dirent_ptr!= NULL)来遍历整个目录。 但由于READDIR()将处理结构的memmory分配我只是声明的dirent结构,让READDIR()完成其工作。 Unfourtatnly出于某种原因的dirent结构被初始化为NULL(也可能是我的编译器),所以永远不会启动我的循环,因为它是有条件的说法是不正确initialy。 所以我想我的问题是我在做什么错在这里?

这里是重要的变量声明和包含的图书馆的。 请注意,所有这些变量都globaly声明。

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include <string.h>

int recursive_delete(const char *path);
int file_delete(const char *path, int file_size);

struct dirent *direntp;
struct stat *statp;

struct switches
{
    int verbose;
    int no_prompt;
    int continue_if_error;
    int files_only;
}; struct switches switches;

而不是解决我相对路径简单地cd到作为参数给出的路径,然后我使用。 和..通配符扔directorys移动,使得相对路径(d_names)是有效的。 同时将开关结构只包含命令行开关,并应被忽略,我知道下面的代码中的错误,但unfourtantly我不能修复他们,因为我不能让过去的上述问题。

int recursive_delete(const char *path)
{
    DIR *dirp;
    int return_value = 0;
    int recursive_return_value = 0;

    if((chdir(path)) == -1)
    {
        perror("ERROR(3)");
        return 1;
    }
    printf("CDED to \"%s\"\n", path);

    dirp = opendir(".");
    if(dirp == NULL)
    {
        perror("ERROR(4)");
        return 1;
    }
    printf("OPENED \"%s\"\n", path);

    while(direntp != NULL)
    {
        direntp = readdir(dirp);
        if( (direntp == NULL) && (errno != 0) )
        {
            perror("ERROR(5)");
            return 1;
        }
        printf("READ \"%s\" FROM \"%s\"\n", direntp->d_name, path);

        if( (strcmp(direntp->d_name, ".")!=0) && (strcmp(direntp->d_name, "..")!=0) )
        {
            if((stat(direntp->d_name, statp)) == -1)
            {
                perror("ERROR(6)");
                return 1;
            }
            printf("STATED \"%s\"\n", direntp->d_name);

            if(S_ISREG(statp->st_mode))
            {
                printf("DELETING \"...\\%s\\%s\"\n", path, direntp->d_name);
                return_value += file_delete(direntp->d_name, statp->st_size);
                if( (!switches.continue_if_error) && (return_value != 0) )
                {
                    break;
                }
            }
            else if(S_ISDIR(statp->st_mode))
            {
                printf("\n\n\nCALLING RECURSIVE DELETE with \"%s\"\n", direntp->d_name);
                recursive_return_value = recursive_delete(direntp->d_name);
                return_value += recursive_return_value;

                if( (!switches.continue_if_error) && (recursive_return_value != 0) )
                {
                    break;
                }

                if( (!switches.files_only) && (recursive_return_value == 0) )
                {
                    if((chdir("..")) == -1)
                    {
                        perror("ERROR(6)");
                        return 1;
                    }
                    printf("CDED BACK TO \"%s\" FROM \"%s\"\n", path, direntp->d_name);

                    if((rmdir(direntp->d_name)) == -1)
                    {
                        perror("ERROR(7)");
                        return 1;
                    }

                    if(switches.verbose)
                    {
                        printf("DELETED DIRECTORY \"...\\%s\\\"\n\n\n", direntp->d_name);
                    }
                }
            }
        }
    }

    return return_value;
}

Answer 1:

你的代码结构应该看起来像thhis(为了清楚省略了大多数错误检查):

int recursive_delete(const char *path)
{
  DIR* dirp = NULL;
  int return_value = 0;
  char* initial_cur_dir = malloc(1000);

  getcwd(initial_cur_dir, 1000);
  chdir(path);
  dirp = opendir(".");

  while (dirp != NULL)
  {
    struct dirent* direntp;
    struct stat stat;

    direntp = readdir(dirp);

    if (direntp == NULL)
      break;

    stat(direntp->d_name, &stat);

    if (S_ISDIR(statp->st_mode))
    {
      if (strcmp(direntp->d_name, ".") && strcmp(direntp->d_name, ".."))
      {
        return_value += recursive_delete(direntp->d_name);
      }
    }
    else if (S_ISREG(statp->st_mode))
    {
      unlink(direntp->d_name);
    }
  }

  if (initial_cur_dir != NULL)
  {
    chdir(initial_cur_dir);
    rmdir(path);
  }

ErrorLabel: // you should goto here when an error is detected

  if (dirp != NULL)
  {
    closedir(dirp);
  }

  if (initial_cur_dir != NULL)
  {
    chdir(initial_cur_dir);
    free(initial_cur_dir);
  }

  return return_value;
}


Answer 2:

从连接的代码,其中direntp正(前初始化目前尚不清楚while循环)。 也许你可以试试:

direntp = readdir(dirp);
while(direntp != NULL)
{
    // all your work here

    direntp = readdir(dirp);
}

这种模式保证了direntp初始化和更新while循环。 然而,在你的代码的第二眼我不完全知道什么是while循环应该在第一时间做的事情。 如何direntpdirp在你的循环变化?

这有可能是你可以逃脱的if测试(而不是while ),只是让递归调用处理“循环”的效果......



文章来源: Do I need to Allocate Memory for a Dirent Structure