繁体   English   中英

在 static 库 function 调用从全局 object

[英]Debug assertion failure when using std::vector in a static library function called from a global object

我目前正在对我的解决方案进行代码清理,其中包括一个 static 库和两个依赖它的应用程序。 作为此代码清理的一部分,我一直在将我的所有循环转换为 std::vectors 以使用迭代器而不是索引。 一切进展顺利,直到我转换了在构建全局 object(在应用程序中)期间调用的 function(在库中)。 有问题的 function 填充 std::vector,然后在向量中搜索与传递给 function 的描述相匹配的 object,返回第一个匹配项。 如果未找到匹配项,则返回向量的前面。

我设法将问题减少到以下代码:

图书馆 - Bar.h

struct Bar
{
    int val;

    Bar(int val = 0);

    static Bar const& ByVal(int val);
};

库 - 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
}

应用程序 - 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:\Work\Reduction\Debug\Foo.exe
File: c:\program files (x86)\microsoft visual studio 10.0\vc\include\vector
Line: 238

Expression: vector iterators not compatible

这是在 Visual Studio 2010 中使用全新项目的全新解决方案。项目上唯一更改的设置是使应用程序链接到 static 库所必需的设置。

为了找出导致崩溃的原因,我发现代码在以下条件下工作:

  • 在发布模式下编译时。
  • 当库的 bar 向量被声明为 extern 并在应用程序本身中定义时。
  • 当应用程序的 foo 变量移动到 main() function 内部时。
  • 当库中的代码完全移动到应用程序时。
  • 在 Visual Studio 2008 下编译时。

任何帮助将不胜感激,即使这意味着要重新使用索引或 VS2008。 近两天来,我一直在疯狂地搜索并在这个问题上猛烈抨击。

C++ 标准不保证bars的构造函数将在foo的构造函数之前被调用。 这有时被称为“静态初始化顺序惨败” 你可能会在 VS2008 中走运,但这并不意味着问题就消失了。 链接的页面为这个问题提出了一些潜在的解决方案,其中之一是使用功能级 static 以确保在使用前对其进行初始化。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM