【问题标题】:what is wrong with the following recursive directory search and file open?以下递归目录搜索和文件打开有什么问题?
【发布时间】:2012-03-03 16:53:21
【问题描述】:

我正在尝试访问一个目录中的所有文件,并对这个目录和后续目录下的文件做一些事情。对于这个操作,我在 windows 中使用了 dirent.h,它设法获取所有文件并打开和关闭这些文件。我的问题是,当我尝试从他们那里读取一些内容并写入另一个内容时,如下所示,我得到了最后显示的错误。

代码如下:

#include <iostream>
#include <cstring>
#include <sys/stat.h>
#include <dirent.h>
FILE *test_file;
char buffer[51];
void listdir(const char *path) 
{
  struct dirent *entry;
  DIR *dp;

  //std::cout << "Dir: " << path << "\n";

  if(dp = opendir(path))
  {
    struct stat buf ;
    FILE *input_file;

    while((entry = readdir(dp)))
    {
        std::string p(path);
        p += "\\";
        p += entry->d_name;
        char fpath[250];
        //strcpy(fpath,path);
        if(!stat(p.c_str(), &buf))
        {
            if(S_ISREG(buf.st_mode))
            {
                std::cout << "    File: " << entry->d_name << "\n";
                sprintf(fpath,"%s\\%s",path,entry->d_name);
                input_file=fopen(fpath,"r+b");
                test_file=fopen("test_test.txt","a+b");
                if(input_file==NULL)
                {
                std::cout<<"\n Could not open\n"<<entry->d_name<<std::endl;
                continue;
                }
                if(test_file==NULL)
                    goto z;
                else 
                {
                    std::cout<<"\n Successfully Opened\n"<<fpath;
                    fread(buffer,50,1,input_file);
                    fprintf(test_file,"\n\n%s\n\n",fpath);
                    fwrite(buffer,50,1,test_file);

                    fclose(input_file);
                     fclose(test_file);
                    // free(buffer);
                }
z:
                if(test_file=NULL)
                fclose(test_file);
            }
            if(S_ISDIR(buf.st_mode) &&  
         // the following is to ensure we do not dive into directories "." and ".."
                      strcmp(entry->d_name, ".")  && strcmp(entry->d_name, "..") )
            {
                listdir(p.c_str());
            }
        }
        else
            std::cout << "ERROR in stat\n";
    }
   // delete buf;
    closedir(dp);
  }
  else
    std::cout << "ERROR in opendir\n";
  fclose(test_file);
}

int main(int argc, char **argv) 
{
  listdir(argv[1]);
  return 0;
}

它设法打开并读取第一个文件,但在第一个文件之后它会显示以下错误并打开 dbgheap.c

HEAP[direntdir.exe]: 为 RtlValidateHeap( 002C0000, 002C5718 ) Windows 在 direntdir.exe。

这可能是由于堆损坏,这表明存在错误 direntdir.exe 或它已加载的任何 DLL。

这也可能是由于用户按下 F12 而direntdir.exe 有 重点。

输出窗口可能有更多的诊断信息。

编辑: 使用 buf 变量更正了错误。

现在我明白了

调试断言失败!

... 表达式:(buffer!=NULL) ...

【问题讨论】:

  • 你在释放和删除buf(这本身就很可疑)和AFAICT,从不在任何地方为它分配存储空间(甚至没有初始化它)。 (C 风格的代码和 C++ 的混合相当混乱。)

标签: c++ c fwrite fread dirent.h


【解决方案1】:

您有两个名为 buf 的变量:

char* buf;
...
struct stat *buf = new struct stat;

后者隐藏了第一个,而后者是free()d,即使它是使用new 创建的,然后被重用而不被重新分配。 后者也用作fread() 的参数。重命名 char* buf 并可能将其设置为函数本地并仅使用堆栈分配的缓冲区:

char fread_buffer[51];

编辑:

char* buffer 在用于fread() 之前从未为其分配内存,因此对fread() 的调用可能会写入内存中的任何位置。改为:

char buffer[50]; /* as only 50 bytes are read from the file */

如果以这种方式声明,请勿在 buffer 上调用 free()

另外,为了简单起见,只需将 buf 声明为:

struct stat buf;

并致电stat():

if(!stat(p.c_str(), &buf))

进行这两项更改将从代码中删除所有动态内存管理。

编辑 2:

这个if 是一个赋值,而不是一个不等式检查:

if(test_file=NULL)
    fclose(test_file);

应该是:

if(NULL != test_file)
    fclose(test_file);

【讨论】:

  • 您是否更改了buffer 的声明?
  • 我根据您的建议更正了我的代码。但现在我得到 Debug Assertion Faild。 .... 表达式(stream==NULL)
  • 我根据您的建议更正了我的代码。但是现在在读取目录中的所有文件后,它会得到运行时错误 Debug Assertion Faild。 .... 表达式(stream==NULL)
  • 包括if (NULL != test_file) ?
  • 没问题:删除free(buffer);,因为buffer不再是动态分配的。
猜你喜欢
  • 2020-10-16
  • 1970-01-01
  • 2012-04-07
  • 1970-01-01
  • 1970-01-01
  • 2012-04-24
  • 1970-01-01
  • 2013-06-07
相关资源
最近更新 更多