Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Access Violation при объявлении структуры OSVERSIONINFO

50K
19 августа 2009 года
rainor
8 / / 19.08.2009
Добрый день. Интересно услышать/прочитать Ваше мнение по интересной ситуации. Суть такова:
ОС 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;
}



Испробованы варианты:
объявления не указателя, а собственно структуры,
выделения памяти из heap,
использования макроса SecureZeroMemory,
передачи в sprintf %u

результат тот же... так сказать "покажите арбуз в профиль"...
перерыты справочники WinAPI, но без успеха, если кто сталкивался поясните в чем может быть проблема.
11
19 августа 2009 года
oxotnik333
2.9K / / 03.08.2007
ну наверно надо OSVERSIONINFO* pOSver = new OSVERSIONINFO;
либо на стеке делать
а так указатель в никуда (в другой объект) тычет
50K
19 августа 2009 года
rainor
8 / / 19.08.2009
память из heap для структуры тоже выделял. Не помогло... валится на строке объявления.
Причем самое смешное, что функция срабатывает и нужное значение возвращает правильно, но ошибка рушит приложение.
11
19 августа 2009 года
oxotnik333
2.9K / / 03.08.2007
вот так работает:
Код:
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;

PS: BCB 6 винда та же
50K
19 августа 2009 года
rainor
8 / / 19.08.2009
Спасибо за подсказку полностью заработало в следующем виде:
Код:
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;
}
14
19 августа 2009 года
Phodopus
3.3K / / 19.06.2008
И чего вы так кучу любите дергать... :)
9
19 августа 2009 года
Lerkin
3.0K / / 25.03.2003
Не всосу: приложение падает, когда встречает
 
Код:
OSVERSIONINFO OSver;
    ZeroMemory( &OSver, sizeof(OSVERSIONINFO) );
вот такой код?


Ни за что не поверю.
50K
21 августа 2009 года
rainor
8 / / 19.08.2009
падает :) причем с завидной регулярностью... я тоже не сторонник выделять память, но сам компилятор видимо создавал структуру в занятой области памяти... так как дебаггер при падении тыкал именно на строку объявления на инструкции eax

справедливости ради надо отметить, что функция эта работает в приаттаченной dll'ке в отдельном потоке открытом с помощью _beginthread, и мое предположение состоит в том, что в соседнем потоке тоже что-то пыталось работать с данным участком памяти, так как сама функция, как я уже писал выполняется верно и результат возвращается, но при этом кладется напрочь хост-аппликэйшн
11
21 августа 2009 года
oxotnik333
2.9K / / 03.08.2007
Цитата: rainor
падает :) причем с завидной регулярностью... я тоже не сторонник выделять память, но сам компилятор видимо создавал структуру в занятой области памяти... так как дебаггер при падении тыкал именно на строку объявления на инструкции eax

справедливости ради надо отметить, что функция эта работает в приаттаченной dll'ке в отдельном потоке открытом с помощью _beginthread, и мое предположение состоит в том, что в соседнем потоке тоже что-то пыталось работать с данным участком памяти, так как сама функция, как я уже писал выполняется верно и результат возвращается, но при этом кладется напрочь хост-аппликэйшн


смотри свои соседние потоки... глюки могут порыться совсем в другом месте
PS:
у тебя pszOSver - массив из 256 указателей
ты уверен что он нормально инициализирован до вызова ф-ции?

14
21 августа 2009 года
Phodopus
3.3K / / 19.06.2008
Цитата: oxotnik333

ты уверен что он нормально инициализирован до вызова ф-ции?


Да конечно нет, стоит только посмотреть на первоначальный код.
[COLOR="Gray"]пц, куда-то еще и с потоками лезет...[/COLOR]

50K
22 августа 2009 года
rainor
8 / / 19.08.2009
Массив нормально проинициализирован до вызова функции. это не 256 указателей, это указатель на массив из 256 символов (в итоге оставил 64, и то много :) )
просто дело в том, что изначально была задумка (первый пример кода), что функция возвращает строку с версией Win.
В ходе работы задумка преобразовалась в то, что функция не возвращает ничего (void в последнем примере), но по адресу переданному аргументом кладет строку версии...
11
22 августа 2009 года
oxotnik333
2.9K / / 03.08.2007
делай через AnsiString/std::string
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог