Стек вокруг переменной «xyz» был поврежден

Я пытаюсь получить простой фрагмент кода, который я нашел на веб-сайте для работы в 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\0U\0s\0e\0r\0s[...]" -- я интересно, откуда берутся все \0.

  • Мой друг скомпилировал его на Windows XP 32 (также VC++ 2010) и смог без проблем запустить его.

какие-нибудь подсказки/подсказки/мнения?

Спасибо


person tirolerhut    schedule 13.05.2010    source источник
comment
Вы не должны использовать sizeof для массива, он не будет работать с массивом, который вы malloc создали.   -  person bobobobo    schedule 03.12.2010


Ответы (2)


Документ не очень ясен. Возвращаемая строка представляет собой 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 (преобразование строки)

person Ade Miller    schedule 13.05.2010
comment
Это правильный ответ. Кроме того, это C++, а не C. std::wcerr ‹‹ LТекущий фон рабочего стола — ‹‹ oldWallPaper; - person Puppy; 13.05.2010
comment
Я предполагаю, что &oldWallPaper должен быть oldWallPaper - person baye; 05.09.2010
comment
Не могли бы вы уточнить & в &oldWallPaper? - person Hossein; 14.09.2013
comment
Разве второй аргумент не должен быть (_tcslen(oldWallPaper)? SystemParametersInfo(SPI_GETDESKTOPWALLPAPER) требует, чтобы uiParam был размером буфера в символах, а не в байтах. sizeof(oldWallPaper) прерывается при компиляции для Unicode. - person josh3736; 13.11.2013

Каждая функция 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 );

Таким образом, вы можете использовать A версию SystemParametersInfoA(), если вы одержимы отказом от использования Unicode. Однако для записи вы всегда должны пытаться использовать Unicode.

Обычно SystemParametersInfo() — это макрос, который возвращает версию W, если в вашей системе определен UNICODE.

person bobobobo    schedule 03.12.2010