ATL 7 + ATL_MIN_CRT в избранное  новое всё   подписка   модер. 
От: Snax rsdnhttp://altergeo.ru/
Дата: 09.08.02 00:18
Оценка:48 (7)
Добрый день всем, кто не спал ночами, разбираясь, почему
при миграции с ATL3 на ATL7 программа начинает стреляться
в неожиданных местах, посвящается.

НЕ ИСПОЛЬЗУЙТЕ atlmincrt.lib, если не знаете что это
такое. Не знаете? Давайте посмотрим. Исходники MINCRT для
ATL находятся в папочке %InstDir%\Vc7\atlmfc\src\atl\atlmincrt
Берем, например, atlinit.cpp, функцию _atexit:

   nCurrentSize = _msize(__onexitbegin);
   [b]if((nCurrentSize+sizeof(_PVFV)) < ULONG(((const BYTE*)__onexitend-
      (const BYTE*)__onexitbegin)))[b]
   {
        //...
   }


сравниваем с аналогичной из страндартного CRT:

        if ( _msize_crt(__onexitbegin)
                < ((unsigned)((char *)__onexitend -
            (char *)__onexitbegin) + sizeof(_PVFV)) )
        {
            /*
             * not enough room, try to grow the table
             */
            //...
        }


Видите разницу? Нет? Разница в том, где находится + sizeof(_PVFV)
Стандартная CRT все делает правильно, а вот CRT из ATL7 прописывает
два указателя за пределами выделенной памяти.

Это пол-беды. Беда начнется, если произойдет еще один вызов _atexit().
Тут условие наконец-то станет истинным и произойдет вызов
::HeapRealloc(). А дальше как повезет. Возможно программа застрелится,
возможно, что застрелится, но по-позже. Да даже если менеджер кучи
позаботится о криворуких программистах из Редмонда и выделит памяти
на 8 байт больше, чем нужно, ::HeapRealloc(), если и сработает,
то на прописанные мимо 8 байт будут потеряны. Два деструктора
вызваны не будут. Ничего хорошего.

Павел.

P.S. У меня ::HeapRealloc() просто вызывает ::TerminateProcess() :crash:
Редкострое удовольствие было отыскивать эту ошибку ;)