在数组中找不到导致访问冲突的原因

Can't find what's causing access violation in array

!!!我必须坚持使用这些功能,因为不允许我使用任何不同的功能!!!

稍微解释一下我需要做什么:用户输入搜索目录,然后如果没有找到任何内容,则会弹出一条错误消息。如果找到某些东西,我会创建一个单行数组,因为至少找到了一个文件,它会保存找到的文件的名称。然后,如果 FindNextFIle 找到任何内容,我将一行添加到现有数组,这一新行将保存新找到的文件名。

第一个输出是函数的直接输出,第二个是数组的测试输出,以确保其正常工作。然而,说内存访问被侵犯是行不通的,所以我无法继续工作。

它不能正常工作的原因可能有 2 个:

  1. 新行的添加不正确
  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;
}