我有两个用C编写的函数,应该从Windows注册表中读取一些信息。尽管两者使用相同的逻辑,但其中之一会引发错误。
起作用的功能会获取一些CPU信息。
struct CPUInfo {
wchar_t model[128];
DWORD frequency;
};
struct CPUInfo cpuinfo() {
SYSTEM_INFO siSysInfo;
HKEY hKey;
struct CPUInfo cpu = { L"", 0 };
LONG lRes = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0",
0,
KEY_READ,
&hKey
);
if (lRes == ERROR_SUCCESS) {
DWORD dwBufferSize = sizeof(cpu.model);
ULONG nError = RegQueryValueExW(
hKey,
L"ProcessorNameString",
0,
NULL,
(LPBYTE)cpu.model,
&dwBufferSize
);
dwBufferSize = sizeof(DWORD);
nError = RegQueryValueExW(
hKey,
L"~MHz",
0,
NULL,
(LPBYTE)(&cpu.frequency),
&dwBufferSize
);
RegCloseKey(hKey);
}
return cpu;
}
该功能可以正常运行,并且可以从注册表中检索信息。现在,我第二次使用此功能
struct GPUInfo {
DWORD adaptersCount;
};
struct GPUInfo gpuinfo() {
HKEY hKey;
struct GPUInfo gpu = { 0 };
LONG lRes = RegOpenKeyExW(
HKEY_LOCAL_MACHINE,
L"HARDWARE\\DEVICEMAP\\VIDEO",
0,
KEY_READ,
&hKey
);
if (lRes == ERROR_SUCCESS) {
DWORD dwBufferSize = sizeof(DWORD);
ULONG nError = RegQueryValueExW(
hKey,
L"MaxObjectNumber",
0,
NULL,
(LPBYTE)(&gpu.adaptersCount),
dwBufferSize
);
RegCloseKey(hKey);
}
return gpu;
}
如我所说,当我调试程序时,第一个函数可以工作,但是第二个函数在此时抛出异常:
ULONG nError = RegQueryValueExW( // !!!! Access violation reading location 0x0000000000000004
hKey,
L"MaxObjectNumber",
0,
NULL,
(LPBYTE)(&gpu.adaptersCount),
dwBufferSize
);
我已经检查了注册表,并且路径确实存在。真的不明白为什么第一个可行,但是第二个却不可行。我叫他们接连
最佳答案
请注意您的编译器警告。您通过值而不是地址传递lpcbData
(缓冲区长度)。
它看起来应该像这样:
DWORD dwBufferSize = sizeof(gpu.adaptersCount); // (2)
ULONG nError = RegQueryValueExW(
hKey,
L"MaxObjectNumber",
0,
NULL,
(LPBYTE)(&gpu.adaptersCount),
&dwBufferSize // (1)
);
变化:
就像您的第一个示例一样,在
dwBufferSize
前面添加与号使用您的实际结构成员
sizeof
。这是等效的,但面对将来的更改会更安全。参考:
-
RegQueryValueExW
关于c - RegQueryValueExW返回C中的访问冲突读取位置异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54573530/