Статические библиотеки c ++ без mfc, связанные с проектом MFC, генерируют bad_alloc или CMemoryException *? - PullRequest
5 голосов
/ 18 октября 2008

Я работаю над большой устаревшей кодовой базой для приложения MFC. Со временем над этим кодом работали многие разработчики, и в результате в коде есть три различных способа справиться с возможностью сбоя при выделении нового.

Первый способ - проверить NULL на результат new. Мы не используем nothrownew.obj, так что это явно ошибка, которую необходимо устранить.

Второе - перехватывать CMemoryException * (да, исключения C ++ включены в компиляторе). Из того, что я понимаю, MFC переопределяет стандартный оператор new и выбрасывает эту вещь вместо этого. Я совершенно уверен, что этот второй метод является правильным в самом приложении MFC. MFC переопределяет новый, со своей странной версией CMemoryException.

Последнее исходит от нашей базы людей, которые хорошо разбираются в C ++, но не обязательно являются программистами MFC. Они ловят const std :: bad_alloc &.

Чего я действительно не знаю, так это того, что ожидать от статических библиотек, связанных с приложением. Это было подавляющее большинство кода, который использует bad_alloc жизни. Предполагая, что эти библиотеки не скомпилированы с MFC или ATL и написаны только на стандартном C ++, могут ли они ожидать перехвата bad_alloc? Или же присутствие MFC в приложении, на которое они ссылаются, заразит их глобальным новым оператором и сделает их попытки завершиться неудачей из-за неудачного распределения?

Если у вас есть ответ, не могли бы вы объяснить, как это работает, или указать мне правильную ссылку, чтобы разобраться в этом?

Ответы [ 4 ]

3 голосов
/ 18 октября 2008

Это будет зависеть от параметров компиляции статических библиотек, которые будут связаны с приложением.

Если библиотеки скомпилированы с конфигурацией для использования static Стандартного времени выполнения C ++, то я бы ожидал, что operator new из Стандартного времени выполнения C ++ будет вызван.

Если библиотеки скомпилированы с конфигурацией для использования стандартной среды выполнения C ++ DLL , то разрешение этих функций будет отложено до загрузки программы, и должно быть разрешено в MFC замены operator new.

Я также включил ссылку на эту статью Herb Sutter об ошибках распределения дескрипторов, которые могут оказаться полезными.

1 голос
/ 09 марта 2016

Я провел несколько исследований MFC-кода (в VC2010). Вот несколько фактов.

  1. MFC генерирует указатель на глобальный экземпляр CMemoryException с именем "_simpleMemoryException" (см. Также AfxThrowMemoryException ())
  2. это исключение CE, для которого m_bAutoDelete имеет значение false.

Идея: Если возможно изменить c ++ - only-static-library, вы можете переслать объявление class CException; и / или class CMemoryException; в корневое пространство имен.

Добавьте блок catch с catch (CMemoryException* pEx) {...} и / или catch (CException* pEx) {...} в каждом месте, где находится блок std::bad_alloc-catch. Поскольку пойманный указатель является указателем на глобальный объект, нет необходимости вызывать pEx->Delete();.

Таким образом, в c ++ - only-static-library не требуется включать afx.h или / и ссылку на MFC. Я пробовал в VC2010 , и он работает нормально. (только если включен RTTI и только если никто не изменяет MFC-NewHandler с AfxSetNewHandler на что-то другое, чем default-MFC-NewHandler AfxNewHandler)

1 голос
/ 18 октября 2008

Поздравляю - вы, кажется, поставили нас в тупик. : -)

Теоретически, если MFC обеспечивает перегрузку для глобальной функции new, тогда она должна использоваться всем кодом в программе. Но поскольку статические библиотеки были скомпилированы, не зная об этом, я не могу с уверенностью сказать, что это произойдет.

Лучшее, что я могу предложить, - написать тестовый код, чтобы выяснить это. (У меня не будет доступа к моей системе Windows в течение следующих нескольких часов, или я сам сделаю это и дам вам ответ.)

0 голосов
/ 09 марта 2016

Вы можете изменить поведение броска MFC с помощью AfxSetNewHandler(_PNH pfnNewHandler) и указать указатель на свою собственную функцию NewHandler. Эта функция должна затем вызвать исключение std::bad_alloc. Но теперь MFC-части программы имеют проблему с перехватом std::bad_alloc.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...