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