Повреждение кучи при использовании кода DLL - PullRequest
3 голосов
/ 07 октября 2011

У меня есть код, который мне нужно поместить в общую библиотеку DLL. Этот код, класс CalibrationFileData, прекрасно работает, когда он построен как часть текущего проекта. Однако, если в общей библиотеке встроено CalibrationFileData, программа вылетает, упоминая повреждения кучи.

Я позаботился о том, чтобы все выделения и освобождения происходили внутри класса, с соответствующими средствами доступа и т. Д. Тем не менее проблема не исчезнет. На всякий случай, если это имеет какое-то значение, я иногда передаю векторы пар, определенно не простые старые данные, но манипулирование вектором происходит только через методы доступа, поэтому не должно быть никакого распределения между модулями.

Что-нибудь, что мне не хватает?

Редактировать: Векторы:

std::vector<std::pair<CvPoint2D32f, CvPoint3D32f>>* extrinsicCorrespondences;
std::vector<int>* pointsPerImage;

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

Ответы [ 7 ]

4 голосов
/ 07 октября 2011

Проверьте соответствие флагов компиляции между библиотекой и исполняемым файлом. Например, в Windows убедитесь, что вы используете ту же библиотеку времени выполнения C (CRT) (/ MD vs / MT). Проверьте предупреждения от компоновщика.

1 голос
/ 07 октября 2011

Вы уверены, что когда вы переходите во владение содержимым объектов vector в своих методах, вы копируете их в переменные вашего экземпляра?

0 голосов
/ 17 июля 2017

Вы должны различать тесно связанные и слабо связанные DLL с.

Плотно связанные DLL с означают, что

DLL построен с точно такой же версией компилятора, настройками упаковки и соглашения о вызовах, опциями библиотеки в качестве приложения и обе динамически связаны с библиотекой времени выполнения (опция компилятора /MD).Это позволяет передавать объекты туда и обратно, включая контейнеры STL, выделять DLL объекты изнутри приложения, наследовать от базовых классов в другом модуле, делать практически все, что можно, не используя DLL s.Недостатком является то, что вы больше не можете развертывать DLL независимо от основного приложения.Оба должны быть построены вместе.DLL просто для улучшения времени запуска процесса и рабочего набора, потому что приложение может запуститься до загрузки DLL (с помощью опции компоновщика /delayload).Время сборки также меньше, чем у одного модуля, особенно когда используется оптимизация всей программы.Но оптимизация не происходит за границей приложения-DLL.И любое нетривиальное изменение все равно потребует перестройки обоих.

В случае слабо связанных DLL с, тогда

При экспорте DLLфункций, лучше всего, если они принимают только целочисленные типы данных, например int или указатели.

Применительно, например, к строкам, тогда:

Когда вынужно передать строку, передать ее как const char *.Когда вам нужна функция DLL для возврата строки, передайте в DLL указатель char * на предварительно выделенный буфер, где DLL запишет строку.

Наконец,что касается распределения памяти, то:

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

Ссылки

Повреждение кучи при возврате из функции внутри dll

Могу ли я передать std:: строка в DLL?

0 голосов
/ 10 октября 2011

В опции командной строки в Visual Studio удалите этот _SECURE_SCL.В основном этот сбой вызван несоответствием _SECURE_SCL среди деталей.Более подробную информацию можно найти здесь: http://kmdarshan.com/blog/?p=3830

0 голосов
/ 07 октября 2011

Вероятно, вы пропустили какой-то фрагмент кода клиента, который пытается освободить память, выделенную вашей DLL, или наоборот.

Возможно, проще всего было бы убедиться, что и клиент, и DLL используют один и тот же распределитель памяти. Не просто такого же типа, но тот же фактический «экземпляр» распределителя. В Visual C ++ это легче всего достигается с помощью как клиента, так и DLL с помощью библиотеки времени выполнения "Многопоточная отладочная DLL (/ MDd)" или "Многопоточная DLL (/ MD)".

0 голосов
/ 07 октября 2011

Могут ли быть разные значения, определенные для _SECURE_SCL в двух проектах?

0 голосов
/ 07 октября 2011

Вы должны проверить глубокие копии внутри векторного объекта, я думаю, это относится к глубокой копии

...