Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C GetFileAttributesW导致访问冲突读取位置x(GetLastError返回8)_C_Winapi - Fatal编程技术网

C GetFileAttributesW导致访问冲突读取位置x(GetLastError返回8)

C GetFileAttributesW导致访问冲突读取位置x(GetLastError返回8),c,winapi,C,Winapi,我目前正在尝试实现一个程序,将多个文件加载到内存中,以便进一步处理。为了查看文件是否存在,我创建了一个函数,使用GetFileAttributesW检查文件是否确实存在 第一个文件被正确加载,但一旦我尝试加载第二个文件,就会出现访问冲突(GetLastError返回8;ERROR\u内存不足)。我可以安全地排除我没有足够的RAM的可能性,因为文件的最大大小为500kb,而且我从来没有加载超过20个(我有16GB的RAM)。 我也有权访问he文件等 inline BOOL FileExists(c

我目前正在尝试实现一个程序,将多个文件加载到内存中,以便进一步处理。为了查看文件是否存在,我创建了一个函数,使用GetFileAttributesW检查文件是否确实存在

第一个文件被正确加载,但一旦我尝试加载第二个文件,就会出现访问冲突(GetLastError返回8;ERROR\u内存不足)。我可以安全地排除我没有足够的RAM的可能性,因为文件的最大大小为500kb,而且我从来没有加载超过20个(我有16GB的RAM)。 我也有权访问he文件等

inline BOOL FileExists(const TCHAR* szPath)
{
    DWORD dwAttrib = GetFileAttributesW(szPath); // ERROR here (1st iteration everything is fine) 

    return (dwAttrib != INVALID_FILE_ATTRIBUTES && !(dwAttrib & FILE_ATTRIBUTE_DIRECTORY));
}

.
.
.

FILE_DATA LoadFileIntoMemory(const TCHAR* FileName)
{
    PTCHAR FinalPath = VirtualAlloc(NULL, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    PTCHAR FilePath = L"C:\\Users\\invasi0nZ\\"; // 

    concat(FinalPath, FilePath, MAX_PATH);
    concat(FinalPath, FileName, MAX_PATH);

    if (!FileExists(FinalPath))
    {
        memset(FinalPath, 0, MAX_PATH);

        FilePath = L"C:\\Users\\invasi0nZ\\Documents\\";

        concat(FinalPath, FilePath, MAX_PATH);
        concat(FinalPath, FileName, MAX_PATH);
    }

    HANDLE File = CreateFileW(FinalPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

    if (File == INVALID_HANDLE_VALUE)
    {
        return (FILE_DATA){ NULL, NULL };
    }

    int FileSize = GetFileSize(File, NULL);

    PBYTE RawFile = VirtualAlloc(NULL, FileSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);

    DWORD dwRead;
    size_t FileSize = GetFileSize(File, NULL);

    ReadFile(File, RawFile, FileSize, &dwRead, NULL);

    CloseHandle(File);
    VirtualFree(FinalPath, sizeof(FinalPath), MEM_FREE);

    return (FILE_DATA) { RawFile, FileSize };
}

.
.
.

void LoadAllFiles(Array FileNames)
{
    for (int i = 0; i < FileNames.used; i++)
    {
        FILE_DATA file_data = LoadFileIntoMemory(FileNames.array[i].file_name);
        // Store file_data, etc.
    }
    // Do stuff with files here
}
inline BOOL文件存在(const TCHAR*szPath)
{
DWORD dwAttrib=GetFileAttributesW(szPath);//此处出错(第一次迭代一切正常)
返回(dwAttrib!=无效的文件属性&&!(dwAttrib&FILE属性目录));
}
.
.
.
文件\数据加载FileInMemory(常量TCHAR*文件名)
{
PTCHAR FinalPath=VirtualAlloc(NULL,MAX_PATH,MEM_COMMIT,MEM_RESERVE,PAGE_READWRITE);
PTCHAR FilePath=L“C:\\Users\\invasi0nZ\\”;//
concat(最终路径、文件路径、最大路径);
concat(最终路径、文件名、最大路径);
如果(!FileExists(FinalPath))
{
memset(最终路径,0,最大路径);
FilePath=L“C:\\Users\\invasi0nZ\\Documents\\”;
concat(最终路径、文件路径、最大路径);
concat(最终路径、文件名、最大路径);
}
HANDLE File=CreateFileW(FinalPath,GENERIC_READ,File_SHARE_READ,NULL,OPEN_EXISTING,File_ATTRIBUTE_NORMAL,NULL);
if(File==无效的\u句柄\u值)
{
返回(文件数据){NULL,NULL};
}
int FileSize=GetFileSize(文件,NULL);
PBYTE RawFile=VirtualAlloc(NULL,FileSize,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);
德沃德·德雷德;
size\u t FileSize=GetFileSize(文件,NULL);
ReadFile(File,RawFile,FileSize,&dwRead,NULL);
关闭句柄(文件);
VirtualFree(FinalPath、sizeof(FinalPath)、MEM_FREE);
返回(文件\数据){RawFile,FileSize};
}
.
.
.
void LoadAllFiles(数组文件名)
{
for(int i=0;i
就我所见,我正在关闭所有必需的句柄,并在不破坏程序的情况下释放所有可以释放的内容


提前非常感谢

您没有使用
VirtualAlloc()
分配足够的内存,因此
concat()
函数可能导致缓冲区溢出。由于编译时启用了
UNICODE
TCHAR
wchar\t
,大小为2个字节。在为
FinalPath
分配内存时,以及使用
memset()
清除
FinalPath
时,需要考虑该大小

更改此项:

PTCHAR FinalPath = VirtualAlloc(NULL, MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
...
memset(FinalPath, 0, MAX_PATH);
为此:

PTCHAR FinalPath = VirtualAlloc(NULL, sizeof(TCHAR) * MAX_PATH, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
...
memset(FinalPath, 0, sizeof(TCHAR) * MAX_PATH);
您的代码也存在其他问题。在使用返回的指针之前,您不会检查
VirtualAlloc()
是否成功。如果
CreateFileW()
失败,则正在泄漏分配的内存。并且您两次声明
FileSize

请尝试以下方法:

FILE\u数据加载fileinto内存(const TCHAR*FileName)
{
PTCHAR FinalPath=VirtualAlloc(NULL,sizeof(TCHAR)*最大路径,MEM_COMMIT,MEM_RESERVE,PAGE_READWRITE);
如果(!FinalPath)
返回(文件数据){NULL,0};
PTCHAR FilePath=TEXT(“C:\\Users\\invasi0nZ\\”;//
concat(最终路径、文件路径、最大路径);
concat(最终路径、文件名、最大路径);
如果(!FileExists(FinalPath))
{
memset(FinalPath,0,sizeof(TCHAR)*最大路径);
FilePath=TEXT(“C:\\Users\\invasi0nZ\\Documents\\”;
concat(最终路径、文件路径、最大路径);
concat(最终路径、文件名、最大路径);
}
HANDLE File=CreateFile(FinalPath,GENERIC\u READ,File\u SHARE\u READ,NULL,OPEN\u EXISTING,File\u ATTRIBUTE\u NORMAL,NULL);
if(File==无效的\u句柄\u值)
{
VirtualFree(最终路径,0,MEM_发布);
返回(文件数据){NULL,0};
}
VirtualFree(最终路径,0,MEM_发布);
DWORD FileSize=GetFileSize(文件,NULL);
if(FileSize==无效的文件大小)
{
关闭句柄(文件);
返回(文件数据){NULL,0};
}
PBYTE RawFile=VirtualAlloc(NULL,FileSize,MEM_COMMIT | MEM_RESERVE,PAGE_READWRITE);
如果(!RawFile)
{
关闭句柄(文件);
返回(文件数据){NULL,0};
}
德沃德·德雷德;
if(!ReadFile(File,RawFile,FileSize,&dwRead,NULL))
{
VirtualFree(RawFile,0,MEM_发行版);
RawFile=NULL;
dwRead=0;
}
关闭句柄(文件);
返回(文件\数据){RawFile,dwRead};
}
也就是说,您根本不需要
FileExists()
,因为
CreateFile()
可以告诉您该文件是否存在,从而避免在您检查文件是否存在后但在您打开该文件之前,如果另一个进程创建/删除该文件,则代码中会出现争用情况

您还应该摆脱
VirtualAlloc()
对于
FinalPath
,您不需要动态分配该字符串。只需静态声明数组即可

Win32 API具有将路径段连接在一起的函数,因此您无需编写自己的函数。它还具有查询用户配置文件和文档文件夹路径的功能,您不应该硬编码这些路径

请尝试类似以下内容:

#包括
#包括
#包括
句柄OpenFileInFolder(CSIDL FolderID,const TCHAR*文件名)
{
TCHAR文件路径[最大路径];
HRESULT Res=SHGetFolderPath(NULL,FolderID,NULL,SHGFP\u TYPE\u CURRENT,FilePath);
如果(Res!=S_OK)
{
SetLastError(Res);
返回无效的\u句柄\u值;
}
Res=路径组合(文件路径、最大路径、文件路径、文件名);
如果(Res!=S_OK)
{
塞特拉斯特罗