Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > C/C++: Общие вопросы > dll, exe и куча(и) |
Автор: dgolukas 5.6.2010, 08:43 |
господа![]() столкнулась со странной проблемой. есть собственная либа dll в которой есть класс, например "черный ящик" все предназначение черного ящика хранить записывать и вовзращать данные. ну каг-бэ временное хранение данных в определенном формате. так вот есть в этом черном ящике два поля типа std::string так же есть собственное аппликейшн, которое активно юзает этот черный ящик из dll т.е. создает объект класса черный ящик, записывает туда свои данные, читает, снова записывает, снова читает так вот проблема заключается в том, что когда приходит время убивать черный ящик, который как правило объявлен локальной переменной. при вызове деструктора черного ящика все падает с ошибкой HEAP[]: Invalid Address specified to RtlValidateHeap т.е. деструктор пытается удалить стринги из какой-то другой кучи, а не из той где они реально созданы. пс. проблема не исчезает и при замене стрингов чарами. может быть у вас есть какие-нибудь соображения как от этого чуда с двумя кучами избежать? версия компилятора vs6.0 ппс. обе версии проектов debug. |
Автор: Peter 5.6.2010, 09:34 |
Открываем поисковик - и находим: http://msdn.microsoft.com/en-us/library/ms235460(VS.80).aspx |
Автор: dgolukas 5.6.2010, 12:52 | ||
хм тут написано, что This can cause a memory access violation or heap corruption if the DLL and its users use different copies of the CRT libraries. так вот мне не понятно, как я могу использовать различные копии рантайм либрари если я собираю оба проекта в одном компиляторе с одинаковыми настройками??? |
Автор: maxim1000 5.6.2010, 21:47 |
не помню, как в VC6, но в более поздних версиях возможны два варианта использования CRT: в качестве статической или динамической библиотеки при использовании статической версии, линковщик во время сборки dll не может знать о том, что в exe-шнике она уже есть (т.к. в этот момент он вообще про exe-шник не знает), потому влинковывает CRT в dll, по той же причине в exe-шник добавляется второй экземпляр CRT если используется динамическая версия, линковщик оставляет только код для загрузки CRT.dll и ссылки на функции в ней, а уже во время запуска приложение ОС следит за тем, чтобы был подгружен только один экземпляр CRT (на этот раз у ОС есть знания и о exe-шнике, и о dll-ке) Добавлено через 9 минут и 58 секунд тут ещё стоит проанализировать причины того, что собственная либа является dll, а не lib если предполагается, что они будут разрабатываться отдельно, возможно, не всегда иметь синхронные версии (например, подправили dll, отправили пользователю, а exe остался неизменённым), то стоит придерживаться правила, что память освобождается в том же модуле, в котором она была выделена, т.к. рано или поздно dll и exe начнут ссылаться на разные версии CRT (т.к. она обновляется), и станет плохо если же всё всегда синхронно, то тут возможно, больше походит вариант статической библиотекой - тогда вообще никаких проблем с версиями CRT не возникает |
Автор: dgolukas 5.6.2010, 22:53 | ||
спасибо огромное рза разъяснение!!! теперь более-менее понятно но у меня библиотека связана с экзешником статически. и в ней есть несколько классов, в одном нет проблем с деструктором , в другом есть оба класса содержат stl контейнеры и методы обоих классов вызываются в экзешнике вся работа с памятью как её выделение так и освобождение я порвожу в ехе, а в длл я явно не вызываю выделение памяти, возможно, оно происходит в stl, когда я например записываю какие-то данные в поля типа std::string, но тогда непонятно почему в одном классе из этой же бибиотеки проходит все ровно, а во втором творится такая беда может ли это возникать из-за использования assign() или все гораздо прозаичнее и это может возникать из-за передачи параметров из exe в dll по ссылке??? я так поняла, что если подгружать её (собственную библиотеку) динамически, то проблема решится, но мне бы хотелось оставить её в варианте статического связывания |
Автор: Dem_max 6.6.2010, 05:37 |
Делай DLL статический CRT, ихмо это будет более правильным |
Автор: borisbn 6.6.2010, 08:13 |
Есть подозрение, что memory manager тут не причём. Попробуй сделать простенький проект dll с одним классом, включающим string, и такой же простенький exe-шник, использующий эту dll. Погоняй этот тест и убедишься, что ничего не вылетает. А виноваты, скорее всего, какая-нибудь пропись, delete уже удалённого объекта и т.п. |
Автор: dgolukas 6.6.2010, 09:13 | ||
не, именно разница в разных учах. в дебагере когда прогоняла отслеживала адреса, так вот перед вызовом деструктора адрес у стринга например 0x3d.... и тд, а когда попадает на брекпоинт в деструктор там уже адрес 0x100... |