代码之家  ›  专栏  ›  技术社区  ›  Victor O.

如何将向量列表存储为全局变量?

  •  2
  • Victor O.  · 技术社区  · 7 年前

    这里比较棘手的部分是,我收到了一条错误消息(在Visual Studio 2013中运行),据我所知,这与迭代器没有正常工作有关。每当我调用branchList时,就会出现错误消息。向后推(根)和分支列表。resize()。分支列表。size()不会导致错误。

    所以我的问题是:我缺少/不理解什么才能使这项工作成功?如果我放置向量分支列表;在构造函数开始时,一切都按预期工作。然而,这对我没有帮助,因为我以后还需要在其他函数中使用它。

    skeletonBuilder。h:

    class TreeSkeleton {
    
    public:
        TreeSkeleton();
        void growTree();
    };
    

    skeletonBuilder。cpp:

    #include "skeletonBuilder.h"
    #include <cstdint>
    #include <vector>
    
    
    typedef struct branch {
        branch *parent;
        vec3 position;
        vec3 direction;
    } branch;
    
    //used by constructor + "treeGrow" function
    std::vector<branch> branchList = {};
    
    TreeSkeleton::TreeSkeleton() {
        //instantiate the tree root as a starting position.
        branch root;
        root.parent = NULL;
        root.position = vec3(0, 0, 0);
        root.direction = vec3(0, 1, 0); 
    
        branchList.size(); //works fine
        branchList.resize(100); //Crashes here
        branchList.push_back(root); //Crashes here
    }
    
    TreeSkeleton::growTree() {
        //pushing more branches to branchList
    }
    

    主要的cpp:

    #include "skeletonBuilder.h"
    
    TreeSkeleton tree;
    
    int main(int argc, char *argv[]) {
    
        return 0;
    }
    

    我收到的错误消息:

    Unhandled exception at 0x00507077 in OpenGL_project_Debug.exe: 0xC0000005: Access violation reading location 0x40EAAAB4.
    

    错误消息将我带到名为“vector”的文件中的以下代码段:

     #if _VECTOR_ORPHAN_RANGE
    void _Orphan_range(pointer _First, pointer _Last) const
        {   // orphan iterators within specified (inclusive) range
        _Lockit _Lock(_LOCK_DEBUG);
        const_iterator **_Pnext = (const_iterator **)this->_Getpfirst();
        if (_Pnext != 0)
            while (*_Pnext != 0) //<----------------This is the row that it gets stuck on
                if ((*_Pnext)->_Ptr < _First || _Last < (*_Pnext)->_Ptr)
                    _Pnext = (const_iterator **)(*_Pnext)->_Getpnext();
                else
                    {   // orphan the iterator
                    (*_Pnext)->_Clrcont();
                    *_Pnext = *(const_iterator **)(*_Pnext)->_Getpnext();
                    }
        }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   François Andrieux    7 年前

    在实现文件之间不能保证全局对象的初始化顺序。没有办法确切地知道 main.cpp skeletonBuilder.cpp 将首先初始化。就你而言, TreeSkeleton tree 在之前初始化 std::vector<branch> branchList 这导致了你的问题。的构造函数 TreeSkeleton 必须使用未初始化的 branchList 这是未定义的行为。解决方案是以这样的方式放置全局变量,即 放心。

    一个解决方案是 分支列表 局部静态变量。这些变量保证在第一次遇到时初始化。

    class TreeSkeleton {
    
    public:
        TreeSkeleton();
        void growTree();
    
    private:
        static std::vector<branch> & getBranches();
    };
    
    std::vector<branch> & TreeSkeleton::getBranches()
    {
        // branchList is initialized the first time this line is encountered
        static std::vector<branch> branchList;
        return branchList;
    }
    
    TreeSkeleton::TreeSkeleton() 
    {
        //instantiate the tree root as a starting position.
        branch root;
        root.parent = NULL;
        root.position = vec3(0, 0, 0);
        root.direction = vec3(0, 1, 0);
    
        auto & branchList = getBranches();
        branchList.size();
        branchList.push_back(root); // Should be fine now
    }