Microsoft внесла много значительных изменений в Visual C++ 2005. Если Вы создавали проекты в IDE старых версий, то при попытке открыть проект/решение в новой версии будет произведено обновление (разумеется с сохранением резервных копий) файлов *.dsp и *.dsw или *.sln и *.vcproj (в зависимости от версии, которую Вы использовали раньше).
Но что получится, если Ваши (или не Ваши) проекты собираются не из IDE, а с помощью . bat /. cmd или make -файлов из командной строки? Некоторые из таких проектов без изменения могут просто не собраться.
В этой статье я попытаюсь изложить действия, которые придется предпринять, чтобы сделать возможным сборку старого проекта на новом Visual C++ и избавиться от множества предупреждений во время сборки, а также объяснить причины, из-за которых они выводятся.
Deprecated-функции в CRT
Зная, что некоторые функции из CRT являются потенциальным источником проблем безопасности (чаще всего переполнение буфера), Microsoft создала для них безопасные альтернативы. Безопасные функции имеют те же имена, что и оригиналы, только у них есть суффикс _s . То есть, если Вы писали gets , то теперь MS рекомендует использовать ее безопасный аналог gets_s . Синтаксис у них такой же за исключением (на примере gets_s ) добавления целочисленного параметра – максимального количества символов. Для выяснения нового синтаксиса остальных новых безопасных аналогов читайте, как обычно, MSDN .
Как исправить ошибку api-ms-win-crt-runtime-l1-1-0.dll?
Хорошо это или плохо? Я думаю, что на данный момент хорошо. Потому что оставлен выбор: использовать ли старые версии или переходить на новые.
А какие есть минусы? Я вижу три:
- Microsoft неоднократно убирала вещи, помеченные как deprecated. Мы с вами уже натерпелись ушедших ключей из инструментов студии, которые были помечены как deprecated. Это было и в версии 2003, и в версии 2005. Было вопреки тому, что написано о понятии «deprecated» (не рекомендуемое к использованию) в MSDN. Поживем, посмотрим, что выкинут в Visual Studio 2008. Здесь и далее оффтоп будет написан в таких как этот блоках. Из опыта у меня сложилось субъективное отождествление понятия deprecated буквально следующему предупреждению: «Внимание: не юзай это. В следующих версиях это будет убрано!». И это не смотря на то, что слово deprecated с английского переводится как «не рекомендованое», а не «запланировано к уничтожению». Больше всего расстраивают выбрасывания обратной совместимости, ведь они порождают ряд упёртых людей, которые до сих пор сидят на Visual C++ версии 6 только потому, что их проекты вхлам не собираются на новой студии или требуют ТАКИХ усилий, что проще остаться на «шестерке». Обращаюсь именно к таким: «Очнитесь, на дворе 2007 — десять лет прошло! Многие новые создаваемые сегодня SDK и проекты в лице своих разработчиков порой просто не учитывают существование VC++ 6, а о том, как 6-рка относится к стандарту — промолчим, ладно? Пожалуйста, не начинайте новые проекты на старье». От убранных ключиков пусть несильно, но страдают разработчики, продвинутые пользователи или тестировщики (которым, к примеру, надо собирать свежие снапшоты). Возьмите парочку серьезных проектов на make-файлах для шестой студии, попробуйте собрать. Сразу почувствуете, о чем речь. Не везде же есть родные студийные проекты, которые, к слову сказать, конвертируются порой просто идеально, да еще и с логом предупреждений и советов.
- Любая проверка, пусть даже самая простенькая, требует дополнительных затрат, а это неизбежное падение производительности. И если использование безопасных функций на Вашей машине для Ваших нужд в маленьких редко используемых утилитах повысит безопасность и практически никак не отразится на производительности, то представьте себе, как это отразится на производительности корпоративных сетевых приложений. А ведь время — деньги. Может быть, со мной кому-то сейчас и захотелось поспорить относительно падения производительности, сказать, что это вряд ли будет более хотя бы пары процентов при сегодняшних мощах компьютеров, а с учетом желания максимальной безопасности это не такая уж и большая плата. Да, скорее всего в зависимости от частоты вызова таких функций падение вряд ли будет ощутимым, НО! Какие объемы обрабатываемой информации Вы себе представили, с какой частотой происходят запросы, сколько человек одновременно штурмуют сервер(а)? Вы представляете себе абстрактную базу с тысячами записей или с миллионами? Вы представляете себе организацию с сотнями сотрудников или корпорацию с тысячами сотрудников? И, наконец, вы представляете себе серверы/кластеры, оснащенные по последнему слову техники за бешеные деньги или наши российские реалии? Призадумались?…
- Зная, сколько проблем безопасности можно было бы избежать во многих программах, будь мы все изначально обязаны неизбежно проверять границы буферов и прочее, кажется, что давно пора было что-то подобное сделать и все — проблем нет. Мысль обманчивая. Идея, безусловно, отличная (хотя и не новая). Но что бы там Microsoft не придумывали, это все равно не избавит Вас от всех возможных проблем.
На мой взгляд, особых причин тотально переходить на новые функции нет. Почему? А все просто: есть куски кода, в которых в манипулирование данными пользователь вмешаться не способен. Эти проверенные и отлаженные куски кода можно и нужно оставлять без проверок.
Урок 1. Инструменты СкетчАп. Часть 1. Бесплатные уроки по SketchUp на русском для начинающих.
Но когда дело касается ЛЮБЫХ мест в программе, в которые пользователь или какие-то другие внешние по отношению к программе обстоятельства могут каким бы то ни было образом взаимодействовать с программой, вот тут самое место для таких функций или собственных оберток с проверкой (что, кстати, не создает таких проблем при портировании, как *_s-функции). Итак, еще раз (ИМХО): лучше тщательно продумывать сценарии работы пользователей, анализировать места, которые нуждаются в контроле входных данных, и двигаться в сторону безопасности только там, где это действительно необходимо, а не плодить оверхеды под руководством MS во всех местах.
Итак, что непосредственно нужно сделать, чтобы cl не беспокоил Вас по поводу Deprecated-функций (а в больших проектах эта ругань достигает достаточно приличных размеров): Перед включением заголовочных файлов CRT нужно написать:
#define _CRT_SECURE_NO_DEPRECATE
В противном случае cl будет атаковать Вас сообщениями вроде:
test.cpp(6) : warning C4996: ‘gets’ was declared deprecated. test.cpp(7) : warning C4996: ‘fopen’ was declared deprecated. test.cpp(11) : warning C4996: ‘sprintf’ was declared deprecated.
Однопоточной CRT больше нет
Как мы помним, издавна в Microsoft Visual C++ были разные типы CRT: отладочные и релизные, динамически и статически линкуемые, многопоточные и однопоточные. Так вот обращаю Ваше внимание на последнюю пару.
В новой версии 2005 отсутствует однопоточная версия CRT . Мне жаль, что Microsoft так поступила, потому что, во-первых, статическая однопоточная версия была меньше многопоточной, во-вторых, по понятным причинам однопоточная версия работала эффективнее многопоточной в программах (преимущественно консольных), в которых вся работа всегда проходила в одном потоке. Для таких программ использование многопоточной версии CRT было вредно по всем параметрам. И я, и Вы этим давно и успешно пользовались. И вот те на… Зачем это сделали я объяснить не могу. Так что смело сносите ключ компилятора -ML . Он больщше не знает, что это такое.
Как теперь быть без однопоточной CRT?
Что делать, если однопоточной CRT больше нет, а использовать многопоточную CRT со всеми ее свойствами не очень хочется? Придать однопоточное поведение многопоточной CRT частично можно.
Далее временно под словом поток я буду понимать поток ввода/вывода (I/O Stream), а под словом нить (thread) — поток программного кода, просто потому что эти две вещи в переводе на русский называются одинаково (что вызывает путаницу), хотя слово нить мне как-то не очень симпатизирует в качестве обозначения понятия thread)
-
Итак, в Вашей программе всего одна нить, а в многопоточной (multithreaded) CRT все потоковые функции блокируют нить, чтобы гарантировать отсутствие конфликтов с другими нитями. Блокировка нити (и, конечно же, разблокировка после) отнимает время. Хотелось бы не блокировать единственную нить. Для этого опять же перед включением заголовков CRT пишем следующую директиву препроцессора:
#define _CRT_DISABLE_PERFCRIT_LOCKS
#include
и в начале программы выполнить:
_configthreadlocale(_DISABLE_PER_THREAD_LOCALE);
Прекомпилированные заголовочные файлы (Precompiled headers)
Как раньше было замечательно: написал ключик -YX и забыл. Нет заголовков – создаются, есть – используются… Красота! Была.
Теперь этого ключа не существует. Остались только -Yc и -Yu . Поначалу мне показалось, что теперь пользоваться PCH будет не так удобно, но позже выяснилось, что в действительности заголовки, которые было бы разумно всегда иметь предварительно cкомпилиорванными добавляются/удаляются/изменяются настолько редко, что уже сейчас -YX кажется плюшкой для совсем уж ленивых.
IDE
В IDE (кроме обновленного интерфейса, который, конечно, первым сразу же бросается в глаза) существенных изменений и дополнений нет. От IDE из 2003 версии новую среду отличает лишь несколько новых панелей, окно растолстевшееся окно настройки. Обновились Wizard’ы, обогащена функциями технология IntelliSense, подсветка синтаксиса по-прежнему проигрывает colorer’у Игоря Русских. Появилась возможность собирать несколько проектов параллельно, используя при этом ресурсы нескольких процессоров.
OpenMP
В Visual C++ 8 появилась полная поддержка расширений языка новым стандартом OpenMP 2. Это API, позволяющий писать эффективные приложения для мультипроцессорных систем более удобно, нежели другие стандарты. Сегодня уже доступны (кстати, не так уж и дорого!) двухъядерные процессоры, процессоры с технологией HyperThreading (суперкомпьютеры, пожалуй, оставим за пределами статьи), т. е. пользователям уже доступны аппаратные технологии, позволяющие решать задачи быстрее за счет распараллеливания их на нескольких процессорах. Поэтому сегодня при разработке игр, мультимедиа-кодеков и т.п. ПО стоит задумываться о программировании с поддержкой параллельных вычислений, т.к. на многопроцессорной системе программный код, написанный в расчете на один процессор быстрее выполняться не станет.
Поддержка OpenMP включается ключом компилятора /openmp , а в коде проверяется определенностью символа препроцессора _OPENMP . Управление распараллеливанием осуществляется при помощи директив препроцессора и функций. В случае, если Вы ограничиваетесь лишь директивами, то больше ничего не нужно, а если требуется вызывать функции, то в программу необходимо включить omp.h и линковать на библиотеку vcompd.dll / vcomp.dll (debug/release соответственно).. Если Вас заинтересовала эта технология, то я рекомендую прочитать статью Реализация многопоточности без лишних усилий. В ней довольно простым языком и с примерами показаны основы параллельного программирования с OpenMP.
Собираем Perl::DBI и DBD::InterBase
Сейчас я на конкретном примере покажу, с чем придется столкнуться при переезде на Visual C++ 2005. Эти модули для языка Perl были выбраны не случайно. Я помню, что при их установке приходится кое-что сделать, прежде чем что-то заработает. Заодно, может быть, встречу еще что-нибудь упущенное ранее о VC++ 2005 и напишу здесь.
Итак, беру DBI версии 1.50 (свежайший на момент написания). Ставить буду на ActivePerl версии 5.8.8 от ActiveState. Развернул архив, пошел в получившуюся папочку. Пускаю там Makefile.PL , отработал. Командую nmake … синий экран! Здрастьте, давно не виделись. Если и у Вас то же самое, знайте, в этом виноват Outpost Firewall Pro. Тут придется его либо снести, либо компилировать в безопасном режиме (чтобы он не мешался).
При выполнении nmake даже с не запущенным Аутпостом (не знаю, как в других случаях, но на DBI стабильно) винда падает в синий экран. Идем дальше. Снова nmake. Повалились warning’и о deprecated функциях. Добавляю в начало DBI.xs и Driver_xst.h строку #define _CRT_SECURE_NO_DEPRECATE . После этого nmake clean , Makefile.PL и снова nmake . Собралось.
На первый взгляд это так. На самом деле не работает. Дело оказалось в том (опять же подчеркиваю, в данном конкретном случае!), что dll-ка DBI собирается связанной с MSVCR80.dll (это CRT), и в таком варианте не работает. Почему это происходит, сколько раз ни ставил – никогда не разбирался и сейчас не буду. Тем более, что CRT в DLL не устраивает.
Кстати, при линковке на CRT DLL новый линкер помимо непосредственно связывания с DLL через таблицу импорта творит еще и xml-файлик подобный манифесту для XP Common Controls и вписывает туда Assembly Microsoft.VC80.CRT, что по-видимому и означает как раз тот самый CRT DLL, но, что интересно, если на машине с виндой не ниже XP нет такого файла, ОС говорит, что приложение неверно настроено и что его переустановка решает проблему. Извините. Если под «неверно настроено» Microsoft теперь понимает отсутствие DLL, то у меня просто нет слов. Ну и откуда, спрашивается, пользователь (не такой как я или Вы, уважаемый читатель, раз Вы до сюда дочитали) узнает о том, что именно является причиной неработоспособности приложения (а именно: отсутствие некой dll), и уж тем более что нужно сделать (а именно: временно переместить манифест из папки приложения), чтобы выяснить, в какой именно dll несчастное приложение испытывает нужду?
Откуда берётся связь с MSVCR80.dll ? Лезем в Makefile . Там и лежит ответ на вопрос. Меняем везде msvcrt.lib на libcmt.lib и -MD на -MT . Ключ -MT по-прежнему можно использовать, хотя смысла в этом нет. Многопоточная CRT в VC++ 8.0 используется по умолчанию. Makefile отредактировали, теперь пробуем снова. Собралось. dumpbin /imports DBI.dll показывает, что все получилось как хотелось. nmake install .
Теперь давайте поставим DBD::InterBase (0.44 на сегодня свежайшая версия). Опыт борьбы с DBI здесь пригодится, но и тут не без особенностей. Поначалу все также: пускаю Makefile.PL, отвечаю на вопросы, где у меня FireBird, где его SDK… Oops!
I can’t find your MS VC++ installation. DBD::InterBase cannot build.
Makefile.PL подсказывает, что его разработчик до сих пор не догадывается о существовании каких-то еще версий VC++ кроме 6.0 и 7.0 (утрирую). Поможем скрипту найти VC++ 8.0 : меняем строку
$sw->; на $sw->;
Пробуем, идет дальше, но валится на выполнении теста по созданию базы с помощью isql. Позаменял кое-где юниксовые slash’ы на виндовые – не помогло. Тогда в ответ на «Full path to your test database:» пишу «localhost:c:test.gdb» (в linux можно было хост не указывать, создавал на локальном). Он мне в ответ: «localhost:c:test.fdb does not exist.» (а откуда ему быть-то до создания?).
Создал, снёс и сотворил-таки makefile. nmake . Снова наслушался про deprecated. Заткнул при помощи #define _CRT_SECURE_NO_DEPRECATE. Теперь без лишнего шума можно разглядеть, что все собирается. Но и здесь линкуемся с пресловутой MSVCR80.DLL. Делаю s/msvcrt.lib/libcmt.lib/gi; и в Makefile. Затем снова компилирую и… Eureka! dumpbin (из зависимостей лишь kernel, perl, fbclient), nmake install , работает 🙂
Еще раз, кратко и по делу
Да, прочитать все это было, может быть, и полезно, но в результате все равно в памяти должен остаться самый сок материала. Я помогу Вам, вставив тут непосредственно код и ключи с кратчайшими комментариями.
Удалить ключи компилятора:
-ML -YX -Og -G3, -G4, -G5, -G6, -G7, -GB
Заменить ключи компилятора:
-GX на -EH (Подробнее в MSDN) -Gf на -GF (Подробнее в MSDN) -Op на -fp (Подробнее в MSDN) -Fr на -FR (Подробнее в MSDN)
// Не выводить предупреждения о небезопасных функциях #define _CRT_SECURE_NO_DEPRECATE // Использовать неблокирующие I/O-функции // Улучшает производительность однопоточных программ #define _CRT_DISABLE_PERFCRIT_LOCKS // Одна локаль на все потоки #include _configthreadlocale(_DISABLE_PER_THREAD_LOCALE); Если компилятор ругается блоками наподобие: . somefile(123) : see reference to class template instantiation . with [ . ] то надо добавить ключ -EHsc
Следующий ключ заставит компилироваться код, который рассчитывает на то, что переменные, объявленные в цикле for продолжают существовать после тела цикла. В противном случае такие переменные будут являться локальными только для тела цикла (по стандарту).
-Zc:forScope-
Размер time_t по умолчанию теперь равен 64 бита.
Материал не претендует на полноту охвата и 100% достоверность. Наверняка в будущем еще найдется чем пополнить и улучшить эту статью. Более подробно об отличиях новой версии VC++, как обычно, можно почитать в MSDN. А пока остается Вам пожелать легкого перехода и поменьше граблей.
Источник: dj-andrey.ru
Методы отладки CRT
При отладке программы, которая использует библиотеку времени выполнения C, эти методы отладки могут оказаться полезными.
Использование библиотеки отладки CRT
Библиотека среды выполнения C (CRT) обеспечивает расширенную поддержку отладки. Чтобы использовать одну из библиотек отладки CRT, необходимо связать с /DEBUG и скомпилировать с /MDd помощью , /MTd или /LDd .
Основные определения и макросы для отладки CRT можно найти в файле заголовка .
Функции в отладочных библиотеках CRT компилируются с отладочными сведениями (/Z7, /Zd, /Zi, /ZI (формат отладочной информации)) и без оптимизации. Некоторые функции содержат утверждения для проверки передаваемых им параметров, для них приведен исходный код. Исходный код позволяет войти в функцию CRT, чтобы убедиться, что она работает в соответствии с ожиданиями, а также проверить функцию на наличие некорректных параметров или состояний памяти. (Некоторые технологии CRT являются собственными и не предоставляют исходный код для обработки исключений, операций с плавающей запятой и некоторых других процедур.)
Дополнительные сведения о различных библиотеках времени выполнения см. в разделе Библиотеки времени выполнения C.
Макросы для создания отчетов
Для отладки можно использовать _RPTn макросы и _RPTFn , определенные в , чтобы заменить использование инструкций printf . Вам не нужно заключать их в #ifdef директивы, так как они автоматически исчезают в сборке выпуска, когда _DEBUG не определен.
| _RPT0 , _RPT1 , _RPT2 , _RPT3 , _RPT4 | Выводит строку сообщения и от нуля до четырех аргументов. Для _RPT1 по _RPT4 строка сообщения служит строкой форматирования в стиле printf для аргументов. |
| _RPTF0 , _RPTF1 , _RPTF2 , _RPTF3 , _RPTF4 | То же, что и _RPTn , но эти макросы также выводит имя файла и номер строки, где находится макрос. |
Рассмотрим следующий пример.
#ifdef _DEBUG if ( someVar > MAX_SOMEVAR ) printf( «OVERFLOW! In NameOfThisFunc( ), someVar=%d, otherVar=%d.n», someVar, otherVar ); #endif
Этот код выводит значения someVar и otherVar в stdout . Вызов _RPTF2 можно применить для отчета об этих значениях плюс имя файла и номер строки:
if (someVar > MAX_SOMEVAR) _RPTF2(_CRT_WARN, «In NameOfThisFunc( ), someVar= %d, otherVar= %dn», someVar, otherVar );
Некоторым приложениям могут потребоваться отладочные отчеты, которые не предоставляются макросами из библиотеки времени выполнения C. В таком случае можно написать свой собственный макрос, удовлетворяющий конкретным требованиям. Например, в один из файлов заголовков можно включить следующий код, чтобы определить макрос с именем ALERT_IF2 :
#ifndef _DEBUG /* For RELEASE builds */ #define ALERT_IF2(expr, msg, arg1, arg2) do <> while (0) #else /* For DEBUG builds */ #define ALERT_IF2(expr, msg, arg1, arg2) do < if ((expr) (1 == _CrtDbgReport(_CRT_ERROR, __FILE__, __LINE__, msg, arg1, arg2))) _CrtDbgBreak( ); >while (0) #endif
Один вызов может ALERT_IF2 выполнять все функции printf кода:
ALERT_IF2(someVar > MAX_SOMEVAR, «OVERFLOW! In NameOfThisFunc( ), someVar=%d, otherVar=%d.n», someVar, otherVar );
Пользовательский макрос можно легко настроить для передачи большего или меньшего объема информации в разные места назначения. Этот подход полезен по мере развития требований к отладке.
Написание функций отладочных ловушек
Вы можете написать несколько типов пользовательских функций перехватчика отладки, которые позволяют вставлять код в некоторые предопределенные точки в обычной обработке отладчика.
Функции-ловушки клиентского блока
Если нужно проверить или вывести данные, хранящиеся в блоках типа _CLIENT_BLOCK , можно написать для этого специальную функцию. Создаваемая функция должна иметь прототип, аналогичный следующему, как определено в :
void YourClientDump(void *, size_t)
Другими словами, функция-перехватчик должна принимать void указатель на начало блока выделения вместе со значением size_t типа, указывающим размер выделения, и возвращать void . В противном случае его содержимое за вас.
После установки функции перехватчика с помощью _CrtSetDumpClient она будет вызываться при каждом _CLIENT_BLOCK дампе блока. _CrtReportBlockType можно применять для получения сведений о типе или подтипе выводимых блоков.
Указатель на передаваемую _CrtSetDumpClient функцию имеет тип _CRT_DUMP_CLIENT , как определено в :
typedef void (__cdecl *_CRT_DUMP_CLIENT) (void *, size_t);
Функции-ловушки выделения
Функция перехватчика выделения, установленная с помощью _CrtSetAllocHook , вызывается при каждом выделении, перераспределении или освобождении памяти. Этот тип ловушек можно использовать для различных целей. Используйте их, например, для проверки, как приложение обрабатывает ситуации недостатка памяти, или для оценки шаблонов выделения, или для регистрации данных о выделении для дальнейшего анализа.
Помните об ограничении использования функций библиотеки среды выполнения C в функции обработчика выделения, описанной в разделе Выделение перехватчиков и выделение памяти crt.
Функция-ловушка выделения должна иметь следующий пример:
int YourAllocHook(int nAllocType, void *pvData, size_t nSize, int nBlockUse, long lRequest, const unsigned char * szFileName, int nLine )
Указатель, который вы передаете _CrtSetAllocHook , имеет тип _CRT_ALLOC_HOOK , как определено в :
typedef int (__cdecl * _CRT_ALLOC_HOOK) (int, void *, size_t, int, long, const unsigned char *, int);
Когда библиотека времени выполнения вызывает ваш перехватчик, аргумент указывает, nAllocType какая операция выделения будет выполнена ( _HOOK_ALLOC , _HOOK_REALLOC или _HOOK_FREE ). В случае освобождения или перераспределения, pvData содержит указатель на пользовательскую часть освобождаемого блока.
Однако в случае выделения памяти этот указатель пуст, так как выделение еще не произошло. Остальные аргументы содержат размер выделения, тип блока, номер последовательного запроса и указатель на имя файла. Если он доступен, аргументы также включают номер строки, в которой было выполнено выделение.
После того как функция-перехватчик выполняет любой анализ и другие задачи, необходимые ее автору, она должна вернуть либо TRUE значение , указывающее, что операция выделения может продолжаться, либо FALSE , указывающая, что операция должна завершиться сбоем. Простой обработчик этого типа может проверить объем памяти, выделенный на данный момент, и вернуться FALSE , если этот объем превысил небольшой предел. Затем приложение будет испытывать ошибки выделения, которые обычно возникают только при нехватке доступной памяти. Более сложные ловушки могут отслеживать структуру выделения, анализировать использование памяти или сообщать о возникновении какой-либо определенной ситуации.
Выделение перехватчиков и выделение памяти CRT
Важным ограничением функций-перехватчиков выделения является то, что они должны явно игнорировать _CRT_BLOCK блоки. Это выделения памяти, создаваемые внутри библиотеки CRT ее функциями при любом вызове функций CRT, выделяющих внутреннюю память. Вы можете исключить блоки _CRT_BLOCK из обработки путем добавления в начало функции-ловушки выделения следующего кода:
if ( nBlockUse == _CRT_BLOCK ) return( TRUE );
Если ловушка обрабатывает блоки _CRT_BLOCK , то любая вызываемая в ней функция CRT может привести к выполнению в программе бесконечного цикла. Например, printf осуществляет внутреннее выделение.
Если код перехватчика вызывает printf , то в результате выделения будет снова вызываться перехватчик, который будет вызываться printf снова, и т. д., пока стек не переполняется. Если нужен отчет об операциях выделения _CRT_BLOCK , есть способ обойти это ограничение — для форматирования и вывода использовать функции Windows API вместо функций CRT. Так как функции API-интерфейсов Windows не используют кучу библиотеки CRT, они не могут привести к выполнению в приложении бесконечного цикла.
Если вы изучите исходные файлы библиотеки времени выполнения, вы увидите debug_heap_hook.cpp , _CrtDefaultAllocHook что функция обработчика выделения по умолчанию (которая просто возвращает TRUE ) находится в отдельном файле. Если вы хотите, чтобы обработчик выделения вызывался даже для выделений, сделанных кодом запуска во время выполнения, который выполняется перед функцией приложения main , можно заменить эту функцию по умолчанию одной из собственных, а не использовать _CrtSetAllocHook .
Отчетные функции-ловушки
Функция перехватчика отчетов, установленная с помощью _CrtSetReportHook , вызывается при каждом _CrtDbgReport создании отчета об отладке. Помимо всего прочего их можно использовать для фильтрации отчетов, которые позволяют отобрать выделения конкретного типа. Функция перехватчика отчетов должна иметь прототип, как в следующем примере:
int AppReportHook(int nRptType, char *szMsg, int *retVal);
Указатель, который вы передаете _CrtSetReportHook , имеет тип _CRT_REPORT_HOOK , как определено в :
typedef int (__cdecl *_CRT_REPORT_HOOK)(int, char *, int *);
Когда библиотека времени выполнения вызывает функцию-перехватчик, nRptType аргумент содержит категорию отчета ( _CRT_WARN , _CRT_ERROR или _CRT_ASSERT ), szMsg содержит указатель на полностью собранную строку сообщения отчета и retVal указывает, следует ли _CrtDbgReport продолжать нормальное выполнение после создания отчета или запуска отладчика. (При retVal нулевом значении продолжается выполнение, значение 1 запускает отладчик.)
Если обработчик полностью обрабатывает соответствующее сообщение, поэтому дальнейшие отчеты не требуются, он должен вернуть . TRUE Если возвращается FALSE , _CrtDbgReport сообщение будет передаваться в обычном режиме.
В этом разделе
- Версии отладки функций выделения кучи Рассматриваются специальные отладочные версии функций выделения кучи, в том числе то, как CRT сопоставляет вызовы, преимущества их явного вызова, как избежать преобразования, отслеживание отдельных типов выделений в клиентских блоках и результаты неопределения _DEBUG .
- Сведения о куче отладки CRT Описывает управление памятью и отладочную кучу, типы блоков в отладочной куче, функции отчетов о состоянии кучи и способы использования отладочной кучи для отслеживания запросов на выделение.
- Поиск утечек памяти с помощью библиотеки CRT Рассматриваются способы обнаружения и изоляции утечек памяти с помощью отладчика и библиотеки времени выполнения языка C (CRT).
См. также
- Отладка машинного кода
- Безопасность отладчика
Источник: learn.microsoft.com
Как открыть файлы CRT в Windows 10 [FULL GUIDE]


Если вам интересно, как открыть файл CRT в Windows 10, вы пришли в нужное место. Файл CRT — это файл, который содержит информацию о сертификате, используемом защищенными веб-сайтами. Доступ к файлам в формате CRT также возможен на разных устройствах и в разных программах, использующих сертификаты.
В этой статье мы рассмотрим различные способы открытия файлов CRT с вашего ПК с Windows 10. Читай дальше, чтобы узнать больше.
Как просмотреть сертификаты в Windows?
1. Используйте команду certmgr.msc в диалоговом окне «Выполнить»
- Нажмите клавиши Win + R -> введите команду certmgr.msc -> нажмите Enter.
- Внутри окна диспетчера сертификатов -> найдите нужный сертификат внутри левой панели.
- Выбор сертификата на левой панели покажет вам детали на правой панели.
- Дважды щелкните сертификат, который вы хотите открыть, и используйте ключ для расшифровки файла.
Нужно установить корневые сертификаты на Windows 10? С этим руководством это очень просто!
2. Используйте Windows 10, чтобы открыть сертификат

- Вы также можете просто дважды щелкнуть ваш файл .crt, чтобы Windows открыла его. Откроется окно Сертификат, в котором вы можете увидеть все детали этого сертификата.
- После проверки правильности всего диапазона информации вы можете просто нажать кнопку «Установить сертификат» для применения изменений.
- В зависимости от среды, в которой вы хотите использовать сертификат, данные будут установлены автоматически.
3. Откройте файл .crt внутри вашего любимого браузера
- Щелкните правой кнопкой мыши файл .crt -> выберите Открыть с помощью.
- Выберите программное обеспечение браузера, в котором вы хотите открыть сертификат в -> установите флажок Всегда использовать это приложение, чтобы открывать файлы .crt, если вы хотите, чтобы это было ПО по умолчанию для открытия файлов .crt.
- Нажмите ОК.
В этой статье мы рассмотрели некоторые из лучших вариантов программного обеспечения, которые позволяют открывать файлы .crt в операционной системе Windows 10. Мы надеемся, что это руководство помогло вам понять процесс.
Пожалуйста, не стесняйтесь сообщить нам, помогло ли вам это руководство, используя раздел комментариев, найденный ниже.
ЧИТАЙТЕ ТАКЖЕ:
- Как исправить ошибку Mshtml.dll не найдена [QUICK FIX]
- Что делать, если Защитник Windows 10 удалил мои файлы
- Сбор необходимой информации Ошибка установщика Windows [QUICK FIX]
Источник: gadgetshelp.com