unk*_*own 4 c++ pointers stl list segmentation-fault
我有一个名为vertex的结构,我创建了一些指向它们的指针.我想要做的是将这些指针添加到列表中.下面的代码,当它试图将指针插入列表时,会产生分段错误.有人可以解释一下发生了什么吗?
#include <iostream>
#include <list>
#define NUM_VERTICES 8
using namespace std;
enum { WHITE, GRAY, BLACK };
struct vertex
{
int color;
int distance;
char parent;
};
int main()
{
//create the vertices
vertex r = {WHITE, NULL, NULL};
//create pointer to the vertex structures
vertex *pr = &r;
//create a list to hold the vertices
list<vertex*> *r_list = new list<vertex*>;
list<vertex*>::iterator it;
r_list->insert(it, pr);
}
Run Code Online (Sandbox Code Playgroud)
GMa*_*ckG 10
这里有几个问题.
首先,你没有初始化迭代器,就像其他人说的那样:
list<vertex*>::iterator it = r_list->begin();
Run Code Online (Sandbox Code Playgroud)
这样做,你的代码就可以了.但是你的代码是以糟糕的方式完成的.
为什么要从堆中分配列表?看看你的代码:你有内存泄漏.你不是delete r_list
在任何地方打电话.这就是为什么你应该使用智能指针(std::unique_ptr
,std::shared_ptr
如果你有C++ 11,升压等效否则:boost::scoped_ptr
和boost::shared_ptr
)
但更好的是,只需在堆栈中执行:
//create a list to hold the vertices
list<vertex*> r_list;
list<vertex*>::iterator it = r_list->begin();
r_list.insert(it, pr);
Run Code Online (Sandbox Code Playgroud)
另外,使用迭代器插入是很重要的事情.只需使用push front()或push back():
//create a list to hold the vertices
list<vertex*> r_list;
r_list.push_back(pr);
Run Code Online (Sandbox Code Playgroud)
另一件事:如果你的列表比你构建的顶点更长,它将指向无效的东西.
例如:
// global
list<vertex*> r_list;
void some_function(void)
{
//create the vertices
vertex r = {WHITE, NULL, NULL};
//create pointer to the vertex structures
vertex *pr = &r;
r_list.push_back(pr);
} // right here, vertex r stops existing: the list now contains an
// invalid pointer.
Run Code Online (Sandbox Code Playgroud)
一种解决方案是存储指向堆分配顶点的指针:
// global
list<vertex*> r_list;
void some_function(void)
{
//create the vertices
vertex *r = new vertex;
r->color = WHITE;
r->distance = 0;
r->parent = 0;
r_list.push_back(r);
}
Run Code Online (Sandbox Code Playgroud)
现在,即使在函数之后,列表也指向一个有效的堆分配顶点.现在有一个问题,当你完成使用列表时,你需要通过lsit并调用delete
每个元素.使用Boost指针容器库可以解决此问题.
但最好的方法是只存储顶点(而不是指向它们的指针):
//create a list to hold the vertices
list<vertex> r_list;
//create the vertices
vertex r = {WHITE, NULL, NULL};
r_list.push_back(r);
Run Code Online (Sandbox Code Playgroud)
如果给顶点一个构造函数,你甚至可以就地构造它们:
struct vertex
{
int color;
int distance;
char parent;
vertex(int _color, int _distance, char _parent) :
color(_color),
distance(_distance),
parent(_parent)
{
}
};
//create a list to hold the vertices
list<vertex> r_list;
r_list.push_back(vertex(WHITE, NULL, NULL));
Run Code Online (Sandbox Code Playgroud)
(这些现在不在您的问题中)
首先,NULL通常仅在处理指针时使用.由于distance
和parent
不是指针,用于0
初始化它们,而不是NULL
:
//create the vertices
vertex r = {WHITE, 0, 0};
Run Code Online (Sandbox Code Playgroud)
其次,使用constants
而不是#define
:
#define NUM_VERTICES 8 // <- bad
const int NumberVertices = 8; // <- good
Run Code Online (Sandbox Code Playgroud)
最后,为枚举命名,或将其放在命名空间中:
enum Color { WHITE, GRAY, BLACK };
Run Code Online (Sandbox Code Playgroud)
希望这些帮助!
归档时间: |
|
查看次数: |
22761 次 |
最近记录: |