使用 ReadFile 对内存位置的无效访问
Posted
技术标签:
【中文标题】使用 ReadFile 对内存位置的无效访问【英文标题】:Invalid access to memory location with ReadFile 【发布时间】:2018-02-06 18:54:35 【问题描述】:我有一个文件,C:\demo\Demo.txt,上面有一个简单的“Hello, world”。我想将路径作为参数传递给我的应用程序,用CreateFile
打开它,用ReadFile
读取它并在控制台上显示该行。但是,我收到错误代码998
:
对内存位置的访问无效。
这是我的代码:
int wmain(int argc, WCHAR **argv)
if (argc != 2)
fwprintf(stderr, L"\nWrong arguments. \n");
return 1;
// CreateFile function variables
HANDLE hSourceFile;
LPCWSTR fileName = (LPCWSTR)argv[1];
DWORD desiredAccess = FILE_GENERIC_READ;
DWORD shareMode = FILE_SHARE_READ;
DWORD creationDisposition = OPEN_EXISTING;
DWORD flagsAndAttributes = FILE_ATTRIBUTE_NORMAL;
//---------------------------------------------------------------
// Opening file for reading data
hSourceFile = CreateFileW(
fileName,
desiredAccess,
shareMode,
NULL,
creationDisposition,
flagsAndAttributes,
NULL);
if (hSourceFile != INVALID_HANDLE_VALUE)
wprintf(L"\nThe source file, %s, is open. \n", fileName);
else
wprintf(L"Error code: %u\n", GetLastError());
// ReadFile function variables
LPVOID dataRead=NULL;
DWORD bytesToRead = 100;
DWORD bytesWritten = 0;
//-----------------------------------------------------------------
// Reading data from file
if (!ReadFile(
hSourceFile,
dataRead,
bytesToRead,
&bytesWritten,
NULL))
wprintf(L"Error code: %u\n", GetLastError());
return 1;
wprintf(L"%s. \n", (LPWSTR)dataRead);
CloseHandle(hSourceFile);
return 0;
我第一次使用ReadFile
,所以不知道我做错了什么。
你能帮帮我吗?
【问题讨论】:
LPVOID dataRead=NULL;
-> char dataRead[100];
。 ReadFile
想要一个指向有效内存的指针。
其他不相关的问题:如果hSourceFile == INVALID_HANDLE_VALUE
打印了错误代码,但随后您继续使用ReadFile
,这毫无意义。并且您打印dataRead
缓冲区的内容,而没有确保有一个NUL 终止符。而如果你读到的文件不是用DBCS(双字节字符串)编码的,你就会打印垃圾。
您是否希望ReadFile
更改dataRead
的值?如果它要更改存储在dataRead
中的值,它不会采用指向dataRead
的指针而不是它的值吗?
【参考方案1】:
ReadFile
想要一个指向可以写入数据的缓冲区的指针。你传递的是 NULL,所以你得到了你看到的错误。
我会把代码改成
// ReadFile function variables
static const DWORD bytesToRead = 100;
unsigned char dataRead[bytesToRead];
DWORD bytesWritten = 0;
//-----------------------------------------------------------------
// Reading data from file
if (!ReadFile(
hSourceFile,
dataRead,
bytesToRead,
&bytesWritten,
NULL))
wprintf(L"Error code: %u\n", GetLastError());
return 1;
您遇到的下一个问题是您将指针转换为LPWSTR
,即指向空终止 宽字符串的指针。您的文件是否包含该空终止?还是您需要自己添加?假设文件 不 包含终止,您可能想要:
// ReadFile function variables
static const DWORD bufferSize = 50;
WCHAR buffer[bufferSize+1]; // Leave room for null.
DWORD bytesWritten = 0;
//-----------------------------------------------------------------
// Reading data from file
if (!ReadFile(
hSourceFile,
buffer,
bufferSize*sizeof(WCHAR),
&bytesWritten,
NULL))
wprintf(L"Error code: %u\n", GetLastError());
return 1;
buffer[bytesWritten/sizeof(WCHAR)] = 0; // Null terminate.
wprintf(L"%s. \n", buffer); // Look ma! No cast needed.
【讨论】:
试过了,但它正在打印 ??????????。我试图从 LPVOID 转换为 LPWSTR,以便打印。【参考方案2】:您必须分配一个内存缓冲区来放置读取字节。现在你的指针 dataRead
指向 nullptr
,换句话说,没有任何地方,但是你传递了大小 100,这表明你的指针指的是 100 字节分配的缓冲区,这不是事实。
【讨论】:
我添加了PBYTE dataRead = (BYTE*)malloc(bytesToRead);
并打印了wprintf(L"%s. \n", (WCHAR*)dataRead);
,但我收到了这样的信息:???????。
@SergioCalderon : a) 文件是否包含wprintf
需要的空终止符; b) 文件中实际上是什么?是 WCHAR 字符还是简单的 ASCII? (我会说“用od -c
转储它,但是就像你在Windows 上一样,除非你有cygwin,否则你不会有od
)
我没有将文件保存为 UNICODE,谢谢。以上是关于使用 ReadFile 对内存位置的无效访问的主要内容,如果未能解决你的问题,请参考以下文章
Windows Vista:无法加载 DLL“x.dll”:对内存位置的访问无效。 (DllNotFoundException)