首先插入静态STL集导致未处理的异常0xC0000005:抛出访问冲突

时间:2012-04-18 16:10:13

标签: c++ visual-studio-2008 exception stl set

所以我在VS 2008中使用C ++进行嵌入式环境(ARM处理器)。我为我的公司建立了一个中型项目。到目前为止,它一直是Windows应用程序。我被要求将其更改为控制台应用程序,因为这对此应用程序更有意义。我没有真正的理由让它成为一个Windows应用程序......首先,我只是在VS中更改了相应的设置(我认为),然后重建。它构建得很好,但每次我尝试运行程序时都会在标题中引用异常。我想强调的是,在将程序切换到控制台应用程序之前,该程序运行良好。我也做了彻底清理和重建整个解决方案。

我认为这可能只是我手动更改设置的问题,因此我创建了一个新项目,该项目被设置为控制台应用程序并将所有源/其他相关项目插入其中。一旦我将解决方案中的所有不同项目正确链接在一起,这样就可以很好地构建,但同样的错误出现了。

当程序崩溃时,它会在插入命令中停止,方法如下:

template<class Elem>
Node<Elem>* Node<Elem>::addChild(const Elem& value)
{
    Node<Elem>* newNode = new Node(value);
    newNode->m_pParentNode = this;
    m_childList.push_back(newNode);
    m_sNodeSet.insert(newNode);
    return newNode;
}

m_sNodeSet用于强制执行树中每个节点必须唯一的规则。第一次调用此addChild方法时会发生此错误。此时,m_sNodeSet的大小为零,需要分配一些内存。但抛出的异常是访问冲突,而不是可能预期的Bad Alloc。我尝试在insert语句之前添加一个m_sNodeSet.get_allocator()。allocate(5)来查看是否会执行任何操作,但抛出相同的异常。 m_sNodeSet是一个静态成员变量,如果这会产生影响。

此Node类是我创建的自定义树对象。我已经好几周都没有改变这个树项目中的任何内容了。我不认为我在这个以前没见过的树项目上扔任何东西并且完美地表现出来,所以我认为问题不在于树项目本身。

我确信这不是跨库边界访问STL容器的问题。此错误发生在单个静态库的操作中。

我觉得在我的解决方案中仍然需要更改某些设置才能使其正常工作。解决方案中有几个项目,一个DLL,一个LIB和一个EXE。树是第四个项目,但是这个项目只是放入适当的项目“附加包含”。我只更改了EXE,以便它作为控制台应用程序执行。

如果你们对这里可能存在的问题有所了解,我们将不胜感激。

1 个答案:

答案 0 :(得分:1)

如果您已声明:

// Global scope
// > (quote)The m_sNodeSet is a static member variable,
std::set<Node<Elem>*>   Node<Elem>::m_sNodeSet;

个人注意:前缀m_通常是成员变量的捐赠者(不是静态成员)。因此,你会混淆使用这个前缀的很多人。

如果m_sNodeSet是静态成员,则上面的代码正在之前运行,那么您可能会遇到初始化顺序问题。这很容易解决(见下文)。否则你会有一些内存损坏。

class Node
{

    // Remove this line
    // static std::set<Node*>   m_sNodeSet;
    // Replace with this code
    static std::set<Node*>&  getNodeSet()
    {
        static std::set<Node*>   sNodeSet;
        return sNodeSet;
    }
    // Replace all references to m_sNodeSet with getNodeSet()
}

这是有效的,因为在方法getNodeSet()中,变量sNodeSet是静态的,因此在第一次使用时创建,并在程序的长度内保持活动状态。每次调用都将返回对同一对象的引用。因为它是在第一次调用时创建的,所以当返回到使用点时,它保证是活的(并且是完全构造的)。