在数组中找不到导致访问冲突的原因
Can't find what's causing access violation in array
!!!我必须坚持使用这些功能,因为不允许我使用任何不同的功能!!!
稍微解释一下我需要做什么:用户输入搜索目录,然后如果没有找到任何内容,则会弹出一条错误消息。如果找到某些东西,我会创建一个单行数组,因为至少找到了一个文件,它会保存找到的文件的名称。然后,如果 FindNextFIle 找到任何内容,我将一行添加到现有数组,这一新行将保存新找到的文件名。
第一个输出是函数的直接输出,第二个是数组的测试输出,以确保其正常工作。然而,说内存访问被侵犯是行不通的,所以我无法继续工作。
它不能正常工作的原因可能有 2 个:
- 新行的添加不正确
- 打印数组函数不正确
这是main()
:
system("chcp 1251");
drtctrAr drctr;
drctr = createDAr();
WIN32_FIND_DATA FindFileData;
HANDLE hf;
hf = FindFirstFile(drctr.str, &FindFileData);
while (hf == INVALID_HANDLE_VALUE)
{
printf("Error opening files or no files found!\n Try changing the search directory or correct your input!\n");
return 1;
break;
}
StringArray fileNames;
int len;
fileNames.str = (wchar_t**)malloc(sizeof(wchar_t*) * fileNames.rows);
len = wcslen(FindFileData.cFileName)+1;
fileNames.sym = (wchar_t*)malloc(sizeof(wchar_t) * len);
wcscpy_s(fileNames.sym, len, FindFileData.cFileName);
while (FindNextFile(hf, &FindFileData) != 0)
{
printf("Found file: %ls", FindFileData.cFileName);
printf("\n");
fileNames.rows++;
fileNames.str = (wchar_t**)realloc(fileNames.str, sizeof(wchar_t*) * (fileNames.rows));
int len = wcslen(FindFileData.cFileName) + 1;
fileNames.str[fileNames.rows-1] = (wchar_t*)malloc(sizeof(wchar_t) * len);
wcscpy_s(fileNames.str[fileNames.rows-1], len, FindFileData.cFileName);
}
FindClose(hf);
freeDAr(drctr);
printSA(fileNames);
filterSA(fileNames);
freeSA(fileNames);
system("pause");
return 0;
这是单独的打印函数 .cpp
:
void printSA(StringArray arr)
{
printf("...........................\n");
for (int i = 0; i < arr.rows; i++)
{
for(int j=0;j<arr.sym[i];j++)
printf("Current file: %ls", arr.str[i][j]);
printf("\n");
}
}
还有数组结构本身,忘记添加了:
struct StringArray
{
wchar_t** str = NULL;
wchar_t* sym = NULL;
int rows = 1;
};
遗憾的是,我提到了两个可能的原因,但这并不意味着这些是正确的猜测,在分配数组的一开始,某些事情可能是错误的
fileNames.str = (wchar_t**)malloc(sizeof(wchar_t*) * fileNames.rows);
len = wcslen(FindFileData.cFileName)+1;
fileNames.sym = (wchar_t*)malloc(sizeof(wchar_t) * len);
wcscpy_s(fileNames.sym, len, FindFileData.cFileName);
上述行中存在此问题。您为 str
分配了内存,但没有为类型为 wchar_t*
的 *str
/ str[0]
分配内存。然后将文件名复制到 fileNames.sym
而不是 fileNames.str[0]
,这样一开始就不会发现错误。然后,如果找到第二个文件,则为 fileNames.str[1]
分配内存并将文件名复制到其中。这部分是正确的。
因此当您尝试访问 fileNames.str[0]
的内容时会发生访问冲突异常,因为它是未分配的内存。 如果您打印 fileNames.str[1]
, 就会成功。
以下是根据您提供的代码修改后的版本。这个对我有用。你可以试试。
#include <stdio.h>
#include <windows.h>
typedef struct StringArray
{
wchar_t** str;
int rows;
}StringArray;
void printSA(StringArray arr)
{
printf("...........................\n");
for (int i = 0; i < arr.rows; i++)
{
printf("Current file: %ls", arr.str[i]);
printf("\n");
}
}
int main()
{
system("chcp 1251");
WIN32_FIND_DATA FindFileData;
HANDLE hf;
hf = FindFirstFile(L"D:\*.txt", &FindFileData);
while (hf == INVALID_HANDLE_VALUE)
{
printf("Error opening files or no files found!\n Try changing the search directory or correct your input!\n");
return 1;
break;
}
StringArray fileNames;
fileNames.rows = 1;
int len;
fileNames.str = (wchar_t**)malloc(sizeof(wchar_t*) * fileNames.rows);
len = wcslen(FindFileData.cFileName) + 1;
fileNames.str[fileNames.rows - 1] = (wchar_t*)malloc(sizeof(wchar_t) * len);
wcscpy_s(fileNames.str[fileNames.rows - 1], len, FindFileData.cFileName);
while (FindNextFile(hf, &FindFileData) != 0)
{
printf("Found file: %ls", FindFileData.cFileName);
printf("\n");
fileNames.rows++;
fileNames.str = (wchar_t**)realloc(fileNames.str, sizeof(wchar_t*) * (fileNames.rows));
int len = wcslen(FindFileData.cFileName) + 1;
fileNames.str[fileNames.rows - 1] = (wchar_t*)malloc(sizeof(wchar_t) * len);
wcscpy_s(fileNames.str[fileNames.rows - 1], len, FindFileData.cFileName);
}
FindClose(hf);
printSA(fileNames);
// TODO: Free pointers
// ...
system("pause");
return 0;
}
!!!我必须坚持使用这些功能,因为不允许我使用任何不同的功能!!!
稍微解释一下我需要做什么:用户输入搜索目录,然后如果没有找到任何内容,则会弹出一条错误消息。如果找到某些东西,我会创建一个单行数组,因为至少找到了一个文件,它会保存找到的文件的名称。然后,如果 FindNextFIle 找到任何内容,我将一行添加到现有数组,这一新行将保存新找到的文件名。
第一个输出是函数的直接输出,第二个是数组的测试输出,以确保其正常工作。然而,说内存访问被侵犯是行不通的,所以我无法继续工作。
它不能正常工作的原因可能有 2 个:
- 新行的添加不正确
- 打印数组函数不正确
这是main()
:
system("chcp 1251");
drtctrAr drctr;
drctr = createDAr();
WIN32_FIND_DATA FindFileData;
HANDLE hf;
hf = FindFirstFile(drctr.str, &FindFileData);
while (hf == INVALID_HANDLE_VALUE)
{
printf("Error opening files or no files found!\n Try changing the search directory or correct your input!\n");
return 1;
break;
}
StringArray fileNames;
int len;
fileNames.str = (wchar_t**)malloc(sizeof(wchar_t*) * fileNames.rows);
len = wcslen(FindFileData.cFileName)+1;
fileNames.sym = (wchar_t*)malloc(sizeof(wchar_t) * len);
wcscpy_s(fileNames.sym, len, FindFileData.cFileName);
while (FindNextFile(hf, &FindFileData) != 0)
{
printf("Found file: %ls", FindFileData.cFileName);
printf("\n");
fileNames.rows++;
fileNames.str = (wchar_t**)realloc(fileNames.str, sizeof(wchar_t*) * (fileNames.rows));
int len = wcslen(FindFileData.cFileName) + 1;
fileNames.str[fileNames.rows-1] = (wchar_t*)malloc(sizeof(wchar_t) * len);
wcscpy_s(fileNames.str[fileNames.rows-1], len, FindFileData.cFileName);
}
FindClose(hf);
freeDAr(drctr);
printSA(fileNames);
filterSA(fileNames);
freeSA(fileNames);
system("pause");
return 0;
这是单独的打印函数 .cpp
:
void printSA(StringArray arr)
{
printf("...........................\n");
for (int i = 0; i < arr.rows; i++)
{
for(int j=0;j<arr.sym[i];j++)
printf("Current file: %ls", arr.str[i][j]);
printf("\n");
}
}
还有数组结构本身,忘记添加了:
struct StringArray
{
wchar_t** str = NULL;
wchar_t* sym = NULL;
int rows = 1;
};
遗憾的是,我提到了两个可能的原因,但这并不意味着这些是正确的猜测,在分配数组的一开始,某些事情可能是错误的
fileNames.str = (wchar_t**)malloc(sizeof(wchar_t*) * fileNames.rows); len = wcslen(FindFileData.cFileName)+1; fileNames.sym = (wchar_t*)malloc(sizeof(wchar_t) * len); wcscpy_s(fileNames.sym, len, FindFileData.cFileName);
上述行中存在此问题。您为 str
分配了内存,但没有为类型为 wchar_t*
的 *str
/ str[0]
分配内存。然后将文件名复制到 fileNames.sym
而不是 fileNames.str[0]
,这样一开始就不会发现错误。然后,如果找到第二个文件,则为 fileNames.str[1]
分配内存并将文件名复制到其中。这部分是正确的。
因此当您尝试访问 fileNames.str[0]
的内容时会发生访问冲突异常,因为它是未分配的内存。 如果您打印 fileNames.str[1]
, 就会成功。
以下是根据您提供的代码修改后的版本。这个对我有用。你可以试试。
#include <stdio.h>
#include <windows.h>
typedef struct StringArray
{
wchar_t** str;
int rows;
}StringArray;
void printSA(StringArray arr)
{
printf("...........................\n");
for (int i = 0; i < arr.rows; i++)
{
printf("Current file: %ls", arr.str[i]);
printf("\n");
}
}
int main()
{
system("chcp 1251");
WIN32_FIND_DATA FindFileData;
HANDLE hf;
hf = FindFirstFile(L"D:\*.txt", &FindFileData);
while (hf == INVALID_HANDLE_VALUE)
{
printf("Error opening files or no files found!\n Try changing the search directory or correct your input!\n");
return 1;
break;
}
StringArray fileNames;
fileNames.rows = 1;
int len;
fileNames.str = (wchar_t**)malloc(sizeof(wchar_t*) * fileNames.rows);
len = wcslen(FindFileData.cFileName) + 1;
fileNames.str[fileNames.rows - 1] = (wchar_t*)malloc(sizeof(wchar_t) * len);
wcscpy_s(fileNames.str[fileNames.rows - 1], len, FindFileData.cFileName);
while (FindNextFile(hf, &FindFileData) != 0)
{
printf("Found file: %ls", FindFileData.cFileName);
printf("\n");
fileNames.rows++;
fileNames.str = (wchar_t**)realloc(fileNames.str, sizeof(wchar_t*) * (fileNames.rows));
int len = wcslen(FindFileData.cFileName) + 1;
fileNames.str[fileNames.rows - 1] = (wchar_t*)malloc(sizeof(wchar_t) * len);
wcscpy_s(fileNames.str[fileNames.rows - 1], len, FindFileData.cFileName);
}
FindClose(hf);
printSA(fileNames);
// TODO: Free pointers
// ...
system("pause");
return 0;
}