Почему происходит утечка моей DLL при использовании ее в программе MFC SDI, использующей MFC в качестве библиотеки DLL в Visual Studio 2010? - PullRequest
3 голосов
/ 28 сентября 2011

Это может быть лучше направлено на поддержку Microsoft, но было интересно, если у кого-нибудь были какие-либо идеи относительно того, почему это происходит.

Я создал простую C ++ DLL, такую ​​как:

//simpledll.h
class simpledll {
  public:
    __declspec(dllexport) simpledll();
    __declspec(dllexport) ~simpledll();
}

//someheader.h
#include <string>
const std::string SomeString(L"I'm Leaking");

//simpledll.cpp
#include "simpledll.h"
#include "someheader.h"
//some code to generate memory leak debug messages
simpledll::simpledll(){ /*code to register for memory leak debug messages*/}
simpledll::~simpledll(){}

Затем я делаю универсальное приложение MFC SDI (интерфейс с одним документом), используя настройки по умолчанию в VS 2010. В MainFrm.h я #include "simpledll.h" и создаю переменную-член: simpledll mSimpleDLL;

Вот где это становится интересным.Если я скомпилирую и библиотеку DLL, и приложение MFC, нацеленное на v100 (оба с использованием ключа / MDd), простой запуск, а затем закрытие приложения приводит к утечке памяти.Если я изменю настройку «Использование MFC» в приложении MFC на использование MFC в статической библиотеке, утечка исчезнет.Затем, если я перекомпилирую DLL, предназначенную для v90, и перекомпилирую приложение MFC, используя версию DLL MFC, никакой утечки памяти.Переключите DLL для использования v100 и приложение MFC для использования v90 и без утечки памяти.Фактически, единственная комбинация, которая, по-видимому, вызывает утечку памяти, - это когда и DLL, и целевое приложение MFC v100, и приложение MFC используют MFC в качестве общей DLL.Я даже пытался сделать это с предварительным просмотром разработчика VS11, и при настройке v110 все работало нормально.

Кто-нибудь сталкивался с этой проблемой?Это ограничено только приложением SDI MFC в VS2010?Что может быть причиной этих утечек?Я предполагаю, что это как-то связано с завершением работы DLL до вызова деструктора константы SomeString, но почему использование MFC в качестве DLL влияет на это?

Ответы [ 2 ]

0 голосов
/ 19 января 2014

Два с половиной года спустя ...

Я преобразовал нетривиальное автономное приложение, не использующее MFC, в не-MFC DLL, предназначенную для загрузки программой MFC. Все работало, но отладчик VS 2010 сообщал о бесконечных утечках памяти.

Подсказка состояла в том, что об утечках памяти сообщалось при выходе до вызова функций очистки DLL.

Здесь есть подробное обсуждение с таким же подробным и сложным решением:

http://www.vis -sim.com / 3dsceneBB / viewtopic.php? Т = 1027

, что включает указание зависимостей библиотеки MFC. Однако существует гораздо более простое решение:

  1. В свойствах страниц-> Linker-> Input добавьте имя файла DLL в «Delay Loaded DLLs».
  2. На той же вкладке диалогового окна добавьте файл delayimp.lib в поле «Дополнительные зависимости».

Программная альтернатива (вместе с обсуждением преимуществ и недостатков DLL с задержкой загрузки) может быть найдена здесь:

http://www.codeproject.com/Articles/9428/Delay-Loading-a-DLL

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

Обратите внимание, что это необходимо сделать только для версии DEBUG вашей DLL, чтобы подавить ложные сообщения об утечке памяти. DLL-версия все еще может быть статически связана в версии RELEASE, что позволяет избежать недостатков связанных с задержкой DLL-файлов.

0 голосов
/ 29 сентября 2011

Я полагаю, что это просто вопрос того, в каком порядке SomeString инициализируется по сравнению с вызовом AfxEnableMemoryTracking () (если я правильно помню).Фактически, утечка памяти, вероятно, происходит в других сборках, но SomeString, возможно, был выделен до того, как отслеживание утечки памяти было активировано, или он был выпущен до того, как произойдет проверка (маловероятно, что в примере ничего не очистили).

Вы можете попытаться сделать другую сборку, чтобы показать утечку, назначив новое значение SomeString с более длинной строкой, чтобы убедиться, что новое выделение памяти выполнено.Сделайте это из конструктора Simpledll.Но сначала вам нужно переместить объявление строки внутри файла simpledll.cpp, иначе вы получите новый экземпляр в каждом .cpp, который включает someHeader.h.

Редактировать: это не относится к MFC, это может произойтис любой DLL, но поскольку MFC автоматически включает обнаружение утечки памяти, она становится более заметной в приложениях MFC.

...