Разрушение деструктора - PullRequest
8 голосов
/ 13 августа 2010

Я работаю над приложением Win32 c ++ в Visual Studio.

В одном из исходных файлов у меня есть глобальный объект, как показано ниже.

TestClass tObj;

int main() //Execution starts here
{
}

TestClass определен в другой DLLкак показано ниже.

struct Source
{

};

class TestClass
{
  list<Source> sourceList;
    public:
         TestClass() {}
        ~TestClass() {}
};

Во время работы моего приложения, если я пытаюсь явно закрыть приложение, закрывая окно консоли, происходит сбой в деструкторе TestClass.Callstack показывает, что CrtIsValidHeapPointer не работает.

Просьба помочь мне решить эту проблему.

Ответы [ 6 ]

9 голосов
/ 13 августа 2010

Ваша проблема заключается в том, что различные настройки компилятора / компоновщика между .exe и .dll фактически приводят к тому, что .dll и .exe используют разные реализации стандартной библиотеки:

  • Вы должны использовать одни и те же флаги препроцессора * для сборки как .exe, так и .dll, иначе каждый двоичный файл будет компилироваться с немного различными реализациями.
  • Вы должны связать как .exe, так и .dll с динамической средой выполнения. Двоичные файлы, статически связанные со средой выполнения, получают свою собственную кучу - и в итоге вы выделяете одну кучу и пытаетесь освободить другую.

Чтобы это исправить, перейдите на Project > Properties > Configuration Properties > C/C++ > Code Generation и измените параметр библиотеки времени выполнения на Multi-threaded Debug DLL (/MDd). Это необходимо сделать как для проекта .exe, так и для проекта .dll.

Начиная с Visual Studio 2010, некоторые из этих типов ошибок будут обнаруживаться во время соединения с помощью # pragma detect_mismatch .

* Для всех флагов препроцессора, которые влияют на реализацию стандартной библиотеки

4 голосов
/ 13 августа 2010

Удостоверьтесь, что вы соберете бот EXE и DLL с одинаковым временем выполнения, предпочтительно с динамическим временем выполнения.

1 голос
/ 13 августа 2010

Глобальные объекты инициализируются и уничтожаются средой выполнения C.Они инициализируются до вызова main и уничтожаются после его возврата.

Возможно, ошибка вызвана чем-то, к чему обращается ваш деструктор TestClass (или косвенно из деструктора Source).Код деструктора обращается к недопустимой памяти (или памяти, которая уже была освобождена).

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

1 голос
/ 13 августа 2010

В деструкторе происходит сбой, генерируется исключение из деструктора, который вызывает завершение и сбой вашего приложения. Неполученные исключения

В двух ситуацияхдеструктор называется.Первый - когда объект уничтожается в «нормальных» условиях, например, когда он выходит из области видимости или явно удаляется.Второй случай - когда объект уничтожается механизмом обработки исключений во время разворачивания стека части распространения исключения.Вы должны написать свои деструкторы в соответствии с консервативным предположением, что исключение активно, потому что, если элемент управления покидает деструктор из-за исключения, в то время как другое исключение активно, C ++ вызывает функцию завершения

0 голосов
/ 13 августа 2010

попытайтесь сделать ваш конструктор и деструктор не встроенным, это может помочь.Если ctor и dtor не встроены, оба будут сгенерированы от имени dll, поэтому создание и уничтожение списка <> будут выполняться с одной и той же библиотекой времени выполнения.Как правило, старайтесь избегать прохождения непрозрачных объектов stl через границы dll.Лучше инкапсулировать их как приватных членов в свои собственные классы и предоставлять не встроенные методы для манипулирования такими членами

0 голосов
/ 13 августа 2010

Библиотеки DLL и EXE собраны с использованием одного и того же выравнивания (pack pragma)?

...