保存结构指针的 STL 列表
我有一个名为 vertex 的结构,并创建了一些指向它们的指针.我想要做的是将这些指针添加到列表中.我下面的代码在尝试将指针插入列表时会产生分段错误.有人可以解释发生了什么吗?
I have a structure called vertex and I created some pointers to them. What I want to do is add those pointers to a list. My code below, when it tries to insert the pointer into the list, creates a segmentation fault. Can someone please explain what is going on?
#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);
}
推荐答案
这里有几个问题.
首先,您没有像其他人所说的那样初始化迭代器:
First off, you aren't initializing the iterator, like other's have said:
list<vertex*>::iterator it = r_list->begin();
执行此操作,您的代码就可以了.但是你的代码做得不好.
Do this and your code will be fine. But your code is done in a bad manner.
为什么要从堆中分配列表?查看您的代码:您有内存泄漏.您没有在任何地方调用 delete r_list
.这就是为什么您应该使用智能指针 (std::unique_ptr
, std::shared_ptr
如果您有 C++11,则提升等价物:boost::scoped_ptr
和 boost::shared_ptr
)
Why are you allocating the list from the heap? Look at your code: you have a memory leak. You aren't calling delete r_list
anywhere. This is why you should use smart pointers (std::unique_ptr
, std::shared_ptr
if you have C++11, boost equivalents otherwise : boost::scoped_ptr
and boost::shared_ptr
)
但更好的是,只需在堆栈上执行:
But better yet, just do it on the stack:
//create a list to hold the vertices
list<vertex*> r_list;
list<vertex*>::iterator it = r_list->begin();
r_list.insert(it, pr);
此外,使用迭代器插入是很长的路要走.只需使用 push front() 或 push back():
In addition, using the iterator to insert is going about things the long way. Just use push front() or push back():
//create a list to hold the vertices
list<vertex*> r_list;
r_list.push_back(pr);
另一件事:如果您的列表比您构建的顶点的寿命更长,它将指向无效的东西.
Another thing: if your list outlives the vertex you've constructed, it will be pointing to something invalid.
例如:
// 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.
一种解决方案是存储指向堆分配顶点的指针:
One solution is to store pointers to heap-allocated vertices:
// 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);
}
现在,即使在函数之后,列表也指向了一个有效的堆分配顶点.现在的问题是,当您使用完列表后,您需要通过 lsit 并在每个元素上调用 delete
.使用 Boost Pointer Container Library.
Now even after the function the list is pointing to a valid heap-allocated vertex. This now has the problem that when you're done using the list, you need to go through the lsit and call delete
on each element. This problem is assisted by using the Boost Pointer Container Library.
不过,最好的方法是只存储顶点本身(而不是指向它们的指针):
The best way, though, is to just store vertices themselves (rather than pointers to them):
//create a list to hold the vertices
list<vertex> r_list;
//create the vertices
vertex r = {WHITE, NULL, NULL};
r_list.push_back(r);
如果你给顶点一个构造函数,你甚至可以就地构造它们:
If you give vertex a constructor, you can even just construct them in-place:
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));
(这些现在不在您的问题范围内)
(these are now outside your problem)
首先,NULL 一般只在处理指针时使用.由于 distance
和 parent
不是指针,所以使用 0
来初始化它们,而不是 NULL
:
Firstly, NULL is generally only used when dealing with pointers. Since distance
and parent
are not pointers, use 0
to initialize them, rather than NULL
:
//create the vertices
vertex r = {WHITE, 0, 0};
其次,使用 constants
而不是 #define
:
Secondly, use constants
rather than #define
:
#define NUM_VERTICES 8 // <- bad
const int NumberVertices = 8; // <- good
最后,给你的枚举一个名字,或者把它放在一个命名空间中:
Lastly, give your enum a name, or place it in a namespace:
enum Color { WHITE, GRAY, BLACK };
希望这些帮助!
相关文章