Итак, у меня есть библиотека C++ со статически связанной копией MSVCRT. Я хочу, чтобы каждый мог использовать мою библиотеку с любой версией среды выполнения MSVC. Как лучше всего достичь этой цели?
Я уже достаточно осторожен с тем, как все делается.
- Память никогда не преодолевает барьер DLL для освобождения
- Объекты среды выполнения C++ не передаются через барьеры (например, векторы, карты и т. д., если только они не были созданы на той стороне барьера).
- Между барьерами не передаются дескрипторы файлов или дескрипторы ресурсов.
Тем не менее, у меня все еще есть простой код, который вызывает повреждение кучи.
У меня есть такой объект в моей библиотеке:
class Foos
{
public: //There is an Add method, but it's not used, so not relevant here
DLL_API Foos();
DLL_API ~Foos();
private:
std::map<std::wstring, Foo*> map;
};
Foos::~Foos()
{
// start at the begining and go to the end deleting the data object
for(std::map<std::wstring, Foo*>::iterator it = map.begin(); it != map.end(); it++)
{
delete it->second;
}
map.clear();
}
И затем я использую его из своего приложения следующим образом:
void bar() {
Foos list;
}
После вызова этой функции из любого места я получаю отладочное предупреждение о повреждении стека. И если я действительно позволю ему закончиться, это действительно повредит стек и segfault.
Мое вызывающее приложение скомпилировано с помощью инструментов платформы Visual Studio 2012. Библиотека скомпилирована с помощью инструментов платформы Visual Studio 2010.
Это просто то, что мне абсолютно не следует делать, или я на самом деле нарушаю правила использования нескольких сред выполнения?
map
(потому что это не указатель), а затем уничтожает его. Это, по-видимому, вызывает повреждение стека. Если я перейду к VS2010 и создам свое приложение таким образом, оно будет работать нормально. - person Earlz   schedule 14.11.2013