我有一个Visual Studio 2005解决方案,其中包含几个彼此独立构建的项目。主项目静态链接其他项目。我在其中一个静态链接库中得到了非常奇怪的STL向量损坏。例如,我声明了一个std :: vector然后执行sort( thatVector.begin(), thatVector.end() )
,但是当我调试它并查看反汇编时,我看到了:
std::vector<SomeOtherClass<SomeOtherTemplateType>,std::allocator<SomeOtherClass<SomeOtherTemplateType> > >::begin
奇怪的是,SomeOtherClass
和SomeOtherTemplate
在主项目中被声明,所以这个库应该完全不了解它们。
我已经尝试冻结所有其他线程,认为其中一个可能正在破坏thatVector
,但没有骰子。我完全失去了。有没有人经历过这样的事情?
编译信息: - 主程序/ Zi,自定义优化(基本上是可调试的发布版本) - 静态库/ Zi,/ Od
链接信息: / DEBUG
答案 0 :(得分:5)
问题是库和程序是用不同的编译器选项编译的。结果你有不同的迭代器实现,但具有相同的签名。它是known problem,Microsoft建议编译多个版本的静态链接库和链接可执行文件。
答案 1 :(得分:0)
向量是模板化类型,这意味着引用向量的每段代码都必须知道完整类型。您的库不仅可以了解SomeOtherClass和SomeOtherTemplateType,它们必须了解它们以便引用它们的向量。
在这种情况下,矢量的完整类型为:
std::vector<SomeOtherClass<SomeOtherTemplateType>,std::allocator<SomeOtherClass<SomeOtherTemplateType> > >
...这可能在您的代码中声明如下:
vector<SomeOtherClass<SomeOtherTemplateType> > thatVector;
...分配器解析为默认模板参数。
现在,关于你的腐败问题。关于腐败的性质的信息不多,所以我将做一些假设。 Nameley你在一个模块中分配了向量,并试图在另一个模块中对它做一些事情(比如push_back
),并且当你实际发生损坏时在另一个模块中做某事。令人沮丧的是,在许多这种情况下,腐败发生时并未发现或报告腐败。通常在完全不相关的代码中检测到它。
如果上述假设是正确的,我就可能的原因提出了2条建议:
模块未链接到相同版本&amp;运行时库的味道。尝试确保每个模块链接到同一个CRT(例如,Windows下的多线程调试DLL),然后重试。大多数时候,这就是问题所在。
您正在使用不同的编译器(或同一编译器的不同版本)来创建不同的模块。在这种情况下,向量看起来像一个模块的一件事,看起来像另一个模块的其他东西。有很多线程可以直接讨论这类问题,有关一个例子,请参阅here。