在 LockFileEx 之后调用 ReadFile 时崩溃
Crash when calling ReadFile after LockFileEx
我有几个进程尝试读取和写入同一个文件。我希望他们每个人都锁定文件,以便一次只有一个人访问它。
我试过这个(编辑:这次这是一个完整的测试代码):
#include "stdafx.h"
#include "Windows.h"
bool test()
{
const char* path = "test.txt";
HANDLE hFile = CreateFileA(path,
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
printf("ERROR: Cannot open file %sn", path);
return false;
}
// Lock the file
{
OVERLAPPED overlapped = {0};
BOOL res = LockFileEx(hFile, LOCKFILE_EXCLUSIVE_LOCK, 0, ~0, ~0, &overlapped);
if (!res)
{
printf("ERROR: Cannot lock file %sn", path);
return false;
}
}
DWORD fileSize = GetFileSize(hFile, NULL);
if (fileSize > 0)
{
char* content = new char[fileSize+1];
// Read the file
BOOL res = ReadFile(hFile, content, fileSize, NULL, NULL);
if (!res)
{
printf("ERROR: Cannot read file %sn", path);
}
delete[] content;
}
const char* newContent = "bla";
int newContentSize = 3;
// Write the file
BOOL res = WriteFile(hFile, newContent, newContentSize, NULL, NULL);
if (!res)
{
//int err = GetLastError();
printf("ERROR: Cannot write to filen");
}
// Unlock the file
{
OVERLAPPED overlapped = {0};
UnlockFileEx(hFile, 0, ~0, ~0, &overlapped);
}
CloseHandle(hFile);
return true;
}
int _tmain(int argc, _TCHAR* argv[])
{
bool res = test();
return 0;
}
这在我的计算机上工作正常,该计算机装有Windows 8。但是在我同事的电脑上,它崩溃了,它崩溃了。具体来说,对 ReadFile 和 WriteFile 的调用总是崩溃。
请注意,它永远不会输入带有错误 printfs 的代码路径。此代码不会触发任何错误,除了在 ReadFile 中的位置0x00000000写入(在 Windows 7 上运行时)。
我们还尝试将重叠的结构传递给 ReadFile 和 WriteFile 调用。它可以防止崩溃,但锁不再起作用,文件全部被打乱(不是用这个测试代码,用真正的代码)。
我做错了什么?
看起来你的问题是:
lpNumberOfBytesRead [out, optional] 参数在调用中为 null。
仅当 lpOverlapped 参数不为 NULL 时,此参数才能为 NULL。
http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx
这是你的问题:
您缺少必要的结构成员,并且:
0
、~0
和{0}
都是糟糕的代码,像这样的常量表达式总是会产生未经证实的结果——WINAPI 不像 libc 那样工作,参数并不总是与常量进行比较,而是通过宏和其他预处理器定义本身进行测试,因此传递常量值或使用常量初始化 WINAPI 结构通常会导致这样的错误。
经过多年的实验,我发现只有一种万无一失的方法可以避免它们,我将用更正的代码来表达它:
OVERLAPPED overlapped;
overlapped.hEvent = CreateEvent( ........... ); // put valid parameters here!
UnlockFileEx(hFile, 0 /*"reserved"*/, ULONG_MAX, ULONG_MAX, &overlapped);
请仔细阅读:http://msdn.microsoft.com/en-us/library/windows/desktop/aa365716%28v=vs.85%29.aspx
- 当回溯以零开始时,如何调试崩溃
- 内联映射初始化的动态atexit析构函数崩溃
- 执行函数时导致崩溃的变量
- 程序崩溃并显示"std::out_of_range"错误
- CoInitialize()在单独的线程上崩溃而不返回
- 使用调试/崩溃报告将应用程序部署到客户端
- 为什么所有C++编译器都会崩溃或挂起此代码
- 为什么lambda在clang上崩溃而不是在gcc上崩溃
- 为什么我的多线程作业队列崩溃
- ExtractIconEx:可以工作,但偶尔会崩溃
- 为什么引用传递会导致此崩溃(C++)
- 试图创建流或fopen时程序崩溃
- 类对象数组的问题会导致崩溃
- 排序时无法执行交换操作.我做的时候它会崩溃.为什么
- 为什么要增加导致崩溃的指针
- 在虚幻引擎中删除NXOpen对象时崩溃
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- 应用程序崩溃并显示"symbol _ZdlPvm, version Qt_5 not defined in file libQt5Core.so.5 with link time reference"
- C++ReadFile崩溃问题
- 在 LockFileEx 之后调用 ReadFile 时崩溃