0

我正在尝试访问一个目录中的所有文件,并对这个目录和后续目录下的文件做一些事情。对于这个操作,我在 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 中存在错误。

这也可能是由于用户在direntdir.exe 获得焦点时按了F12。

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

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

现在我明白了

调试断言失败!

...表达式:(缓冲区!=NULL)...

4

1 回答 1

2

您有两个变量名为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 */

如果以这种方式声明,请不要调用free()buffer

此外,为了简化事情,只需声明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);
于 2012-03-03T17:02:10.683 回答