我有两个用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/

10-12 00:01
查看更多