我需要为Dirent结构分配内存吗 平台:Windows XP Service Pack 3 编译器:代码::块版本12.11

我需要为Dirent结构分配内存吗 平台:Windows XP Service Pack 3 编译器:代码::块版本12.11,c,windows,directory,posix,C,Windows,Directory,Posix,我目前正在编写一个程序,使用POSIX目录函数递归删除给定目录。但是我对readdir()及其对应的dirent结构有一个问题。我在readdir中读到,对函数的多次调用将覆盖函数返回的结构中保存的数据。所以我认为readdir()必须为结构本身全部指定memmory,然后简单地将指针地址重新分配给捕获其返回值的结构。我测试了这个理论,我是正确的readdir()为它的成员d_名分配了memmory。我遇到的问题是,当目录流为空时,readdir返回一个NULL指针,因此我使用带有条件(dire

我目前正在编写一个程序,使用POSIX目录函数递归删除给定目录。但是我对readdir()及其对应的dirent结构有一个问题。我在readdir中读到,对函数的多次调用将覆盖函数返回的结构中保存的数据。所以我认为readdir()必须为结构本身全部指定memmory,然后简单地将指针地址重新分配给捕获其返回值的结构。我测试了这个理论,我是正确的readdir()为它的成员d_名分配了memmory。我遇到的问题是,当目录流为空时,readdir返回一个NULL指针,因此我使用带有条件(dirent_ptr!=NULL)的while循环来迭代整个目录。但是因为readdir()将处理结构的memmory分配,所以我只需声明一个dirent结构,并让readdir()完成它的工作。由于某些原因,dirent结构被初始化为NULL(或者它可能是我的编译器),所以我的循环永远不会启动,因为它的条件语句不是initially true。所以我想我的问题是我做错了什么

这里是重要的变量声明和包含的库。请注意,所有这些变量都是全局声明的

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

从所附的代码来看,不清楚direntp的初始化位置(在
while
循环之前)。可能尝试以下方法:

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

    direntp = readdir(dirp);
}
此模式确保为while循环初始化和更新
direntp
。然而,在代码的第二眼中,我并不完全确定while循环首先应该做什么。
direntp
dirp
在您的循环中是如何变化的


您可能只需要执行
if
测试(而不是
while
),然后让递归调用处理“循环”效应…

您的代码结构应该与此类似(为了清楚起见,省略了大多数错误检查):


谢谢你的回复,但我有点不知道这对我有什么帮助。除非我将dirent结构的实际值复制到另一个结构中,否则每次循环启动时声明direntp是毫无意义的,因为readdir()不使用接收其返回值的dirent结构的指针地址。另外,我认为您没有理解更改当前目录的意义。如果我使用上面的代码,相对路径将是有效的,rmdir(direntp->d_name)将返回一个无此类文件或目录错误,因为递归的_delete()将更改cwd。您没有看到结尾处的第二个
chdir()
???我更喜欢使用尽可能少的全局变量,以避免类似竞争条件的事情,并将相关代码和数据保持在一起。我将更新它以修复此问题。感谢您的回复并回答您的问题direntp未初始化它仅在主函数前的空白处全局声明。这是我的问题,我想知道它是如何自己初始化为NULL的。此外,direntp应该保存dirp指向的文件/dir的文件/dir名称,它应该是当前工作目录的目录流的当前索引。哦,我差点忘了,是的,使用if语句而不是循环将起作用,但这将使堆栈溢出的可能性更大,因为该函数将被调用用于原始参数的每个文件和子目录。recursive_delete()的设计目的是,当它在当前工作目录中找到一个子目录时,它应该只调用自身。@JohnVulconshinz关于
direntp
初始化:如果幸运的话,您的声明将被调零(即NULL),但这通常不能保证。我在不同的平台/环境中看到了不同的行为。如果没有显式赋值,指针最初可能会有一些垃圾值。
direntp = readdir(dirp);
while(direntp != NULL)
{
    // all your work here

    direntp = readdir(dirp);
}
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;
}