C++;调用free()时程序崩溃 我在Windows上编写一个C++程序,递归地搜索一个嵌套的目录结构,用于用户指定的文件(名称)。它可以成功地搜索数千个子文件夹(递归,所以深度优先),但不能搜索数千个子文件夹

C++;调用free()时程序崩溃 我在Windows上编写一个C++程序,递归地搜索一个嵌套的目录结构,用于用户指定的文件(名称)。它可以成功地搜索数千个子文件夹(递归,所以深度优先),但不能搜索数千个子文件夹,c++,winapi,directory,64-bit,free,C++,Winapi,Directory,64 Bit,Free,最终,它在调用free()时崩溃,在这里,我释放了文件和目录名的本地(递归调用searchDirectory()函数)数组。想必我在什么地方弄乱了这堆东西 我的目录结构有很多层,但在崩溃时只有8层,并且在崩溃时连续第二次返回调用堆栈 我已经注释掉了大部分调试std::cout行,您将看到对free()的调用,它在searchDirectory()递归函数的末尾崩溃。我使用Win32 API和AM编译64位使用GNU C++编译器。(注意:我重新编译了32位并使用了gdb。这是输出:) 我是如何修

最终,它在调用
free()
时崩溃,在这里,我释放了文件和目录名的本地(递归调用
searchDirectory()
函数)数组。想必我在什么地方弄乱了这堆东西

我的目录结构有很多层,但在崩溃时只有8层,并且在崩溃时连续第二次返回调用堆栈

我已经注释掉了大部分调试
std::cout
行,您将看到对
free()
的调用,它在
searchDirectory()
递归函数的末尾崩溃。我使用Win32 API和AM编译64位使用GNU C++编译器。(注意:我重新编译了32位并使用了gdb。这是输出:)

我是如何修改超出范围的内存的??从我的代码中可以看到,我只是使用malloc()进行分配,在可用范围内使用,然后使用free()

#包括
#包括
#包括
#包括
#包括
#包括
#包括
将文件与文件夹分开作废(WIN32_FIND_DATA[]、WIN32_FIND_DATA[]、WIN32_FIND_DATA[]、int*、int*);
void listFilesInDirectory(char[],WIN32_FIND_DATA[]);
无效搜索目录(char[]);
字符文件名[260]={'\0'};
WIN32_查找_数据空项;
char NullFileName[260]={'\0'};
字符反斜杠[]=“\\”;
字符星[]=“*”;
字符cd[]=”;
字符bd[]=“.”;
无符号整数深度=0;
int main(int argc,字符**argv){
如果(argc>1)
strcpy(文件名,argv[1]);
strcpy(NullEntry.cFileName,NullFileName);
char localPath[]=“\\”;
搜索目录(localPath);

std::cout我不知道它为什么在调用
free()
时崩溃(我可以有根据地猜测),但我知道,在一些gdb调试之后,在主
searchDirectory()
递归函数中,我使用
calloc()
在堆上分配了相当大的内存块,然后忘记了
free()
函数末尾的分配!我已经纠正了我的错误,我的代码可以很好地用于8637个嵌套文件夹的目录结构,其中一些文件夹有数百个文件或子目录。我不知道它的上限是什么,但无论目录结构的深度或宽度如何,都不可能达到,除非当然,遵循win32,最大路径长度是260个字符


问题解决了。谢谢你的评论。

我相信你知道
sizeof(char)
是1?元素1000的数量从何而来?您正在分配固定大小的缓冲区,但从不检查是否即将超出缓冲区。基于
C++
标记,您应该使用
vestor
string
类自动管理已用内存。实际上不需要
新的
malloc<在C++中,代码> >代码> >代码>删除> /代码>和<代码>免费< /代码>。C++为您管理资源。一旦您让它发生,您就已经大大减少了超出分配内存的范围的写入机会。在完成此操作之后,用Unicode替换ANSI编码的使用。@ LeeaviDoDeA建议阅读:你不应该用C++习语来编程。使用C++的特性,让你的生活更轻松。嗨,如果解决方案解决了这个问题,请随时标记你自己来帮助其他人。
warning: HEAP[fn32.exe]:
warning: Heap block at 0B545728 modified at 0B5544B0 past requested size of ed80


Program received signal SIGTRAP, Trace/breakpoint trap.
0x772bee8b in ?? ()
(gdb)
 #include <windows.h>
 #include <iostream>
 #include <cstring>
 #include <string.h>
 #include <algorithm>
 #include <iterator>
 #include <stdlib.h>

void seperateFilesFromFolders(WIN32_FIND_DATA[], WIN32_FIND_DATA [], WIN32_FIND_DATA  [], int *, int *);
void listFilesInDirectory(char[], WIN32_FIND_DATA[]);
void searchDirectory(char[]);

char filename[260] = { '\0' };

WIN32_FIND_DATA NullEntry;

char NullFileName[260] = { '\0' };

char backslash[] = "\\";
char star[] = "*";
char cd[] = ".";
char bd[] = "..";

unsigned int depth = 0;

int main(int argc, char **argv) {

    if (argc > 1)
        strcpy(filename, argv[1]);


    strcpy(NullEntry.cFileName, NullFileName);

    char localPath[] = ".\\";

    searchDirectory(localPath);

    std::cout << "COMPLETED.\n";

    return 0;
}

int cmp(char *a, char *b)   { // returns true (1) if the 2 c-strings match, as it should...

    if(strcmp(a, b)==0)
        return 1;

    return 0;
}


void searchDirectory(char path[])   {

    depth++;

    std::cout << "Entering searchDirectory(), path = " << path << std::endl;

    WIN32_FIND_DATA*  files = (WIN32_FIND_DATA*) calloc(400, sizeof(WIN32_FIND_DATA));
    WIN32_FIND_DATA* dirs = (WIN32_FIND_DATA*) calloc(190, sizeof(WIN32_FIND_DATA));

    if (files == NULL)  {

        std::cout << "FILES == NULL!" << std::endl;
    }
    if (dirs == NULL)   {

        std::cout << "DIRS == NULL!" << std::endl;
    }

    int di = 0;
    int fi = 0;

    char* localPath = (char*) calloc(260, sizeof(char));
    char* temp = (char*) calloc(260, sizeof(char));


    strcpy(localPath, path);

    strcpy(temp, localPath);
    strcat(temp, star);

    WIN32_FIND_DATA* entries = (WIN32_FIND_DATA*) calloc(1000, sizeof(WIN32_FIND_DATA));

    listFilesInDirectory(temp, entries);

    seperateFilesFromFolders(entries, files, dirs, &di, &fi);

    for (int i = 0; i < 400; i++)   {

        if (cmp(files[i].cFileName,NullEntry.cFileName))    {
            //std::cout << "File count for this directory == " << i << std::endl;
            break;
        }

        if (cmp(filename, files[i].cFileName))
            std::cout << "File match found in '" << temp << "'!" << std::endl;
    }

    for (int i = 0; i < 190; i++)   {

        if (cmp(dirs[i].cFileName,NullEntry.cFileName)) {

            //std::cout << "dirs[" << i << "].cFileName is Null." << std::endl;
            break;  
        }
        if (!cmp(dirs[i].cFileName, cd) && !cmp(dirs[i].cFileName, bd)) { // REMEMBER: DON'T RECURSIVELY SEARCH . OR .. !!!!!

            //std::cout << "dirs[" << i << "].cFileName = " << dirs[i].cFileName << std::endl;
            char subdirectory[260] = { '\0' };
            char localPath2[260] = { '\0' };

            strcpy(subdirectory, dirs[i].cFileName);

            strcpy(localPath2, localPath);
            strcat(localPath2, subdirectory);
            strcat(localPath2, backslash);

            searchDirectory(localPath2); 
        }
    }

    std::cout << "Depth = " << depth << std::endl;
    free(files);
    free(dirs);

    std::cout << "Returning from searchDirectory()..." << std::endl << std::endl;
    depth--;
}

void listFilesInDirectory(char path[], WIN32_FIND_DATA entries[])   {

    WIN32_FIND_DATA data;
    HANDLE hFind = FindFirstFile(path, &data);      // DIRECTORY
    int i = 0;

    if ( hFind != INVALID_HANDLE_VALUE )    {

        do  {

            //std::cout << data.cFileName << std::endl;
            entries[i++] = data;
        }
        while (FindNextFile(hFind, &data));

        FindClose(hFind);
    }
    else    {

    }

    std::cout << "There are " << i << " files & directories in the current directory. (" << path << ")" << std::endl;

    for (int j = 0; j < i; j++) {

        //std::cout << entries[j].cFileName << " ";
        if (entries[j].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {

            //std::cout << "DIRECTORY";
        }
        else    {

            //std::cout << "FILE";
        }

        //std::cout << std::endl;
    }

    entries[i] = NullEntry;
    //std::cout << std::endl << std::endl;
    return;
}

void seperateFilesFromFolders(WIN32_FIND_DATA entries[], WIN32_FIND_DATA  files[], WIN32_FIND_DATA  dirs[], int *di, int *fi)   {

    int i = 0;
    while(!cmp(entries[i].cFileName,NullEntry.cFileName))   {

        if (entries[i].dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
            dirs[(*di)++] = entries[i];

        else
            files[(*fi)++] = entries[i];

        i++;
    }

    //std::cout << "Made it out!" << std::endl;
}