2010-05-13 134 views
4

我试图得到一些简单的代码我在网站上发现,在VC++ 2010运行在Windows Vista上64:堆栈被损坏

#include "stdafx.h" 
#include <windows.h> 


int _tmain(int argc, _TCHAR* argv[]) 
{ 
DWORD dResult; 
BOOL result; 
char oldWallPaper[MAX_PATH]; 

result = SystemParametersInfo(SPI_GETDESKWALLPAPER, sizeof(oldWallPaper)-1, oldWallPaper, 0); 

fprintf(stderr, "Current desktop background is %s\n", oldWallPaper); 

return 0; 
} 

它编译,但当我运行它,我总是得到这样的错误:

Run-Time Check Failure #2 - Stack around the variable 'oldWallPaper' was corrupted. 

我不知道是怎么回事错的,但我注意到,那oldWallPaper的价值看起来像“C:\ 0:\ 0 \ 0 U \ 0s \ 0e \ 0r \ 0s [...]“ - 我想知道所有的\ 0s来自哪里。

  • 我的一个朋友编译它的Windows XP 32(也VC++ 2010),并能没有问题

任何线索/提示/意见运行呢?

谢谢

+0

你不应该在数组上使用'sizeof',它将不会在你已经有'malloc''d的数组上工作。 – bobobobo 2010-12-03 12:23:17

回答

4

该文档不是很清楚。返回的字符串是一个WCHAR,每个字符两个字节不是一个,所以你需要分配两倍的空间,否则你会得到一个缓冲区溢出。尝试:

BOOL result; 
WCHAR oldWallPaper[(MAX_PATH + 1)]; 

result = SystemParametersInfo(SPI_GETDESKWALLPAPER, 
_tcslen(oldWallPaper), oldWallPaper, 0); 

参见:

http://msdn.microsoft.com/en-us/library/ms724947(VS.85).aspx

http://msdn.microsoft.com/en-us/library/ms235631(VS.80).aspx(字符串转换)

+0

这是正确的答案。 此外,这是C++,而不是C. std :: wcerr << L“当前桌面背景是”<< oldWallPaper; – Puppy 2010-05-13 17:43:22

+0

非常感谢,伙计们! – tirolerhut 2010-05-15 16:36:03

+2

我想&oldWallPaper应该oldWallPaper – 2010-09-05 09:02:25

3

每个Windows功能有2个版本:

SystemParametersInfoA() // Ascii 
SystemParametersInfoW() // Unicode 

W结束的版本是wide character type(即Unicode)版本的功能。所有你看到的\ 0都是因为你找回的每个字符都是Unicode - 每个字符16字节 - 第二个字节恰好为0.因此,你需要将结果存储在wchar_t数组中,并使用wprintf代替printf

wchar_t oldWallPaper[MAX_PATH]; 
result = SystemParametersInfo(SPI_GETDESKWALLPAPER, MAX_PATH-1, oldWallPaper, 0); 
wprintf(L"Current desktop background is %s\n", oldWallPaper); 

所以,如果你一意孤行,不使用Unicode可以使用A版本SystemParametersInfoA()。但是,对于记录,您应该始终尝试使用Unicode。

通常,SystemParametersInfo()是一个宏,如果在您的系统上定义了UNICODE,则该宏将被评估为W版本。