char* szResult = new char [256];
OSVERSIONINFO* pOSver = new OSVERSIONINFO;
ZeroMemory(pOSver,sizeof(OSVERSIONINFO));
pOSver->dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
if (GetVersionEx((OSVERSIONINFO*) pOSver))
{
sprintf(szResult,"%d.%d-build %d",
(*pOSver).dwMajorVersion,
(*pOSver).dwMinorVersion,
(*pOSver).dwBuildNumber);
}
delete pOSver;
else
{
sprintf(szResult,"undefined");
}
ShowMessage(szResult);
delete[]szResult;
Access Violation при объявлении структуры OSVERSIONINFO
ОС WinXP Pro 5.1 билд 2600 (ситуация аналогична на SP2 и на SP3),
среда разработки Borland C++ Builder 10.0,
при объявлении структуры OSVERSIONINFO приложение вылетает с криком "Access Violation"
код выглядит так:
Код:
char* fnOSver(void)
{
char* szResult;
OSVERSIONINFO* pOSver;
ZeroMemory(pOSver,sizeof(OSVERSIONINFO));
pOSver->dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
if (GetVersionEx((OSVERSIONINFO*) pOSver))
{
sprintf(szResult,"%d.%d-build %d",
(*pOSver).dwMajorVersion,
(*pOSver).dwMinorVersion,
(*pOSver).dwBuildNumber);
}
else
{
sprintf(szResult,"undefined");
}
return szResult;
}
{
char* szResult;
OSVERSIONINFO* pOSver;
ZeroMemory(pOSver,sizeof(OSVERSIONINFO));
pOSver->dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
if (GetVersionEx((OSVERSIONINFO*) pOSver))
{
sprintf(szResult,"%d.%d-build %d",
(*pOSver).dwMajorVersion,
(*pOSver).dwMinorVersion,
(*pOSver).dwBuildNumber);
}
else
{
sprintf(szResult,"undefined");
}
return szResult;
}
Испробованы варианты:
объявления не указателя, а собственно структуры,
выделения памяти из heap,
использования макроса SecureZeroMemory,
передачи в sprintf %u
результат тот же... так сказать "покажите арбуз в профиль"...
перерыты справочники WinAPI, но без успеха, если кто сталкивался поясните в чем может быть проблема.
либо на стеке делать
а так указатель в никуда (в другой объект) тычет
Причем самое смешное, что функция срабатывает и нужное значение возвращает правильно, но ошибка рушит приложение.
вот так работает:
Код:
void fnOSver(char* pszOSver[256])
{
OSVERSIONINFO* pOSver = new OSVERSIONINFO;
ZeroMemory(pOSver,sizeof(OSVERSIONINFO));
pOSver->dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
if (GetVersionEx((OSVERSIONINFO*) pOSver))
{
sprintf(*pszOSver,"%d.%d-build %d",
(*pOSver).dwMajorVersion,
(*pOSver).dwMinorVersion,
(*pOSver).dwBuildNumber);
}
else
{
sprintf(*pszOSver,"undefined");
}
delete pOSver;
}
{
OSVERSIONINFO* pOSver = new OSVERSIONINFO;
ZeroMemory(pOSver,sizeof(OSVERSIONINFO));
pOSver->dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
if (GetVersionEx((OSVERSIONINFO*) pOSver))
{
sprintf(*pszOSver,"%d.%d-build %d",
(*pOSver).dwMajorVersion,
(*pOSver).dwMinorVersion,
(*pOSver).dwBuildNumber);
}
else
{
sprintf(*pszOSver,"undefined");
}
delete pOSver;
}
И чего вы так кучу любите дергать... :)
Код:
OSVERSIONINFO OSver;
ZeroMemory( &OSver, sizeof(OSVERSIONINFO) );
ZeroMemory( &OSver, sizeof(OSVERSIONINFO) );
Ни за что не поверю.
справедливости ради надо отметить, что функция эта работает в приаттаченной dll'ке в отдельном потоке открытом с помощью _beginthread, и мое предположение состоит в том, что в соседнем потоке тоже что-то пыталось работать с данным участком памяти, так как сама функция, как я уже писал выполняется верно и результат возвращается, но при этом кладется напрочь хост-аппликэйшн
Цитата: rainor
падает :) причем с завидной регулярностью... я тоже не сторонник выделять память, но сам компилятор видимо создавал структуру в занятой области памяти... так как дебаггер при падении тыкал именно на строку объявления на инструкции eax
справедливости ради надо отметить, что функция эта работает в приаттаченной dll'ке в отдельном потоке открытом с помощью _beginthread, и мое предположение состоит в том, что в соседнем потоке тоже что-то пыталось работать с данным участком памяти, так как сама функция, как я уже писал выполняется верно и результат возвращается, но при этом кладется напрочь хост-аппликэйшн
справедливости ради надо отметить, что функция эта работает в приаттаченной dll'ке в отдельном потоке открытом с помощью _beginthread, и мое предположение состоит в том, что в соседнем потоке тоже что-то пыталось работать с данным участком памяти, так как сама функция, как я уже писал выполняется верно и результат возвращается, но при этом кладется напрочь хост-аппликэйшн
смотри свои соседние потоки... глюки могут порыться совсем в другом месте
PS:
у тебя pszOSver - массив из 256 указателей
ты уверен что он нормально инициализирован до вызова ф-ции?
Цитата: oxotnik333
ты уверен что он нормально инициализирован до вызова ф-ции?
Да конечно нет, стоит только посмотреть на первоначальный код.
[COLOR="Gray"]пц, куда-то еще и с потоками лезет...[/COLOR]
просто дело в том, что изначально была задумка (первый пример кода), что функция возвращает строку с версией Win.
В ходе работы задумка преобразовалась в то, что функция не возвращает ничего (void в последнем примере), но по адресу переданному аргументом кладет строку версии...
делай через AnsiString/std::string