2017-10-06 80 views
2

我正在創建一個由分支組成的樹。爲了我的工作目的,我需要跟蹤分支,爲了做到這一點,我想將它們存儲在向量列表中。我將vector-list作爲全局變量存儲在此文件中,因爲我想在構造函數和下面的代碼片段中顯示的函數中使用它。如何將矢量列表存儲爲全局變量?

這裏比較棘手的部分是,我收到一條錯誤消息(在Visual Studio 2013中運行),據我所知可能與迭代器沒有正常工作有關。每當我調用branchList.push_back(root)和branchList.resize()時都會出現錯誤消息。 branchList.size()不會導致錯誤。

所以我的問題是:我錯過了什麼/不理解,使這項工作?如果我要放置向量branchList;在構造函數的開始,一切都按預期工作。但是這對我沒有幫助,因爲我以後需要在其他功能中使用它。

我正在使用的文件中的相關代碼片段。

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 
} 

main.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. 

錯誤消息帶我到下面的代碼片斷在一個名爲「矢量」文件:

#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(); 
       } 
    } 
+0

請複製粘貼你得到 – UnholySheep

回答

1

全局對象的初始化順序沒有實現文件之間的保證。沒有辦法知道,而main.cppskeletonBuilder.cpp的全局將首先被初始化。在你的情況下,TreeSkeleton treestd::vector<branch> branchList之前被初始化,這會導致你的問題。 TreeSkeleton的構造函數必須使用未初始化的branchList,這是未定義的行爲。解決方案是放置您的全局變量,以保證訂單

一個解決方案是使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 
} 
+0

更妙的是完全消除全局的*確切*錯誤消息。我沒有看到這些變量需要全局化的好理由,而不是樹中包含的向量(作爲成員或靜態,如果它在所有樹之間共享)以及在主函數內部聲明的樹。 –

+0

好的,我明白你在說什麼,並會嘗試使用你寫的功能。然而,一個問題是struct分支已經在.cpp文件中實現,這意味着「靜態std :: vector ...」不知道「分支」是什麼。 –

+0

如果您需要,您可以將靜態成員函數更改爲實現文件中的自由函數。 –