我正在创建一棵由 Twig 组成的树。为了我的工作,我需要跟踪分支,为了做到这一点,我想将它们存储在 vector 列表中。我将 vector 列表存储为此文件中的全局变量,因为我想在下面的代码片段中所示的构造函数和函数中使用它。
这里最棘手的部分是,我收到一条错误消息(在Visual Studio 2013中运行),据我所知,这与迭代器的工作不正确有关。每当我调用branchList.push_back(root)和branchList.resize()时,都会出现错误消息。 branchList.size()不会导致错误。
所以我的问题是:我缺少/不了解要进行这项工作吗?如果我要放置 vector branchList;在构造函数的开始,一切都按预期进行。但是,这无济于事,因为稍后我还需要在其他功能中使用它。
我正在使用的文件中的相关代码段。
SkeleteBuilder.h:
class TreeSkeleton {
public:
TreeSkeleton();
void growTree();
};
frameworkBuilder.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.
该错误消息将我带到名为“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();
}
}
最佳答案
在实现文件之间不能保证全局对象的初始化顺序。无法知道main.cpp
或skeletonBuilder.cpp
的全局变量将首先被初始化。在您的情况下,TreeSkeleton tree
会在std::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
}
关于c++ - 如何将 vector 列表存储为全局变量?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46606306/