在从全局对象调用的静态库函数中使用std::vector时,调试断言失败
Debug assertion failure when using std::vector in a static library function called from a global object
我目前正在对我的解决方案进行代码清理,该解决方案由一个静态库和两个依赖于它的应用程序组成。作为代码清理的一部分,我已经将std::vector上的所有循环转换为使用迭代器而不是索引。一切都很顺利,直到我转换了一个函数(在库中),该函数在构造全局对象(在应用程序中)期间被调用。所讨论的函数填充std::vector,然后在vector中搜索与传递给函数的描述匹配的对象,返回第一个匹配。如果没有找到匹配项,则返回vector的前端。
我已经设法将问题减少到以下代码:
Library - Bar.h
struct Bar
{
int val;
Bar(int val = 0);
static Bar const& ByVal(int val);
};
Library - Bar.cpp
#include "Bar.h"
#include <vector>
using namespace std;
namespace { vector<Bar> bars; } // It is irrelevant whether bars is in an
// anonymous namespace or not; the results are
// the same.
Bar::Bar(int _val) : val(_val) { }
Bar const& Bar::ByVal(int val)
{
if (bars.empty())
{
bars.push_back(Bar(1));
bars.push_back(Bar(2));
}
#if 1
for (vector<Bar>::const_iterator it = bars.begin();
it != bars.end();
++it) // The assertion fails here. However, when the for loop is
// replaced with a while loop, it's the it != bars.end() part
// that fails.
{
if (it->val == val)
return *it;
}
return bars.front();
#else
for (size_t i = 0;
i < bars.size();
++i)
{
if (bars[i].val == val)
return bars[i];
}
return bars[0];
#endif
}
Application - Foo.cpp
#include <Bar.h>
#include <iostream>
using namespace std;
struct Foo
{
Foo()
{
Bar bar = Bar::ByVal(0);
cout << bar.val << endl;
}
};
Foo foo;
int main(int argc, char** argv)
{
return 0;
}
如果Bar.cpp中的预处理器条件更改为0,则代码执行无误。否则,将显示以下断言:
Debug Assertion Failed!
Program: C:WorkReductionDebugFoo.exe
File: c:program files (x86)microsoft visual studio 10.0vcincludevector
Line: 238
Expression: vector iterators not compatible
这是一个全新的解决方案下的全新项目在Visual Studio 2010。在项目上更改的唯一设置是使应用程序链接到静态库所必需的设置。
在试图找出导致崩溃的原因时,我发现代码在以下条件下工作:
- 在发布模式下编译。
- 当库的bars向量被声明为extern,并在应用程序中定义时。
- 当应用程序的foo变量被移动到main()函数中时。
- 当代码从库完全移动到应用程序时。
- 在Visual Studio 2008下编译时。
任何帮助将是非常感激的,即使这意味着要回到使用索引或VS2008。
c++标准不保证bars
的构造函数会在foo
的构造函数之前被调用。这有时被称为"静态初始化顺序惨败";在VS2008中你可能会很幸运,但这并不意味着问题就会消失。链接的页面为这个问题提供了一些可能的解决方案,其中之一是使用函数级静态来确保在使用前对其进行初始化。
相关文章:
- 尝试使用 std::vector<std::thread时出现静态断言失败错误>
- 字符串化递归的"std::vector<std::vector<...>>"而不使用部分模板函数专用化
- 连接和压缩标准::vector<std::字符串的最佳方法>
- C++从 std::vector<std::function<中删除 std::function>>
- 如何在构造函数初始值设定项列表中使用 n 个元素初始化 std::vector<std::time_t>
- 如何使用 CUDA 将 std::vector<std::string> 复制到 GPU 设备
- 编译错误 std::vector<std::shared_ptr<T>>迭代器和擦除方法
- 将 std::vector<std::unique_ptr<T>> 移动到 std::vector<std::shared_ptr<T>>
- 如何从 boost::container::vector<std::string>::iterator 访问索引和对象?
- 使用 std::vector<std::future<int>> 和 std::async 启动几个线程时中止
- 为什么转置这个 std::vector<std::vector<std::string> > 这么慢?
- 是否有可能在没有复制的情况下传递 std::vector<int> 作为参数来获得 std::vector<std::array<int, 3>>?
- 在 boost::<double>asio::buffer 中使用像 std::vector<std::complex> 这样的参数
- 如何从 std::initializer_list<char const* 构建 std::vector<std::string>>
- 如何检查 std::vector<std::string> 的元素是否以某个子字符串开头?
- 在 std::vector<std::vector 中重新存储内部向量<TYPE>>
- 将 std::vector<std::string> 转换为 const char* const*
- 不能将结构push_back() 转换为 std::vector<std::shared_ptr<theStruct>> theVector
- SWIG:传递一个 std::vector< std::vector <double> >指向 python 的指针
- 将 std::vector<std::p air<const K, V>*> 转换为 std::vector<std::p air<const K, V>&g