1

使用时我得到奇怪的结果RegQueryValueEx,我不知道为什么。

这是我在制作之前设置的RegQueryValueEx

DWORD dataSize;
TCHAR data[256];

我第一次打电话

LONG ret = RegQueryValueEx( hKey, dataKey, NULL, NULL, (LPBYTE)data, &dataSize);

ret等于 234 ( ERROR_MORE_DATA)

但是当我在下一行调用同样的东西时

LONG ret2 = RegQueryValueEx( hKey, dataKey, NULL, NULL, (LPBYTE)data, &dataSize);

ret2等于 0 ( ERROR_SUCCESS)

为什么这个函数会ERROR_MORE_DATA在我第一次调用它时返回,然后ERROR_SUCESS在下一行的同一个调用中返回?

我试图改变TCHAR data[1024],但我得到了完全相同的结果。有任何想法吗?

完整代码:

for( int i=0; i<NUM_HISTORY; i++){
     CString dataKey = getDataKey(i);

     DWORD dataSize = 1024;
     TCHAR data[1024];

     LONG ret = RegQueryValueEx( hKey, dataKey, NULL, NULL, (LPBYTE)data, &dataSize);
     LONG ret2 = RegQueryValueEx( hKey, dataKey, NULL, NULL, (LPBYTE)data, &dataSize);

     // Breakpoint to see what ret and ret2 are equal to
     int j = 0;
}
4

1 回答 1

0

这是设计使然。第一次调用失败,因为您指定的大小太小。但是您没有指望的是它还更新了您的 dataSize 变量。告诉你要分配多少内存才能使调用成功。

所以第二次调用成功了,因为您现在指定了一个完全正确的大小。但不做你需要做的其他事情,实际上使缓冲区更大。当调用然后导致缓冲区溢出并损坏您的堆栈帧时,不会发生什么好事,请务必使用 /RTC 编译选项,这样您就会得到运行时错误。

您通过将缓冲区大小从 256 增加到 1024 避免了这个问题。但是您的代码仍然不正确,如果注册表值变得大于 1024 字节,您的程序将惨遭失败。不要使用本地数组,使用new运算符或 malloc() 来分配缓冲区,这样它就永远不会像这样失败。或者干脆让通话失败并声明“坏数据”。

另请注意另一个错误,dataSize 以字节为单位,但缓冲区是 TCHAR,而不是字节。这可能就是您没有破坏堆栈帧的原因,缓冲区意外地足够大。你不想依赖这样的事故。考虑使用像 CRegKey 这样的辅助类来避免此类错误。

于 2013-07-30T20:10:46.177 回答