STL列出保存结构指针 [英] STL List to hold structure pointers

查看:110
本文介绍了STL列出保存结构指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个称为顶点的结构,我创建了一些指针。我想做的是将这些指针添加到列表。我的代码下面,当它试图插入指针到列表中,创建一个分段故障。有人可以解释发生了什么吗?

  #include< iostream> 
#include< list>

#define NUM_VERTICES 8

使用namespace std;

枚举{WHITE,GREY,BLACK};

struct vertex
{
int color;
int distance;
char parent;
};

int main()
{
//创建顶点
vertex r = {WHITE,NULL,NULL}

//创建指向顶点结构的指针
vertex * pr =& r;

//创建一个保存顶点的列表
list< vertex *> * r_list = new list< vertex *> ;;

list< vertex *> :: iterator it;

r_list-> insert(it,pr);
}


解决方案



首先,你不是初始化迭代器,像其他人说的:

  list< vertex *> :: iterator it = r_list-> begin(); 

这样做,你的代码就可以了。但你的代码是以糟糕的方式完成的。



为什么要从堆中分配列表?看看你的代码:你有一个内存泄漏。您不是在任何地方调用 delete r_list 。这就是为什么您应该使用智能指针( std :: unique_ptr std :: shared_ptr 如果你有C ++ 11,boost等效,否则: boost :: scoped_ptr boost :: shared_ptr



但更好的是,只是在堆栈上:

  //创建一个列表来保存顶点
list< ; vertex *> r_list;

list< vertex *> :: iterator it = r_list-> begin();

r_list.insert(it,pr);

此外,使用迭代器插入是很漫长的事情。只需使用推送前面() push back()

  //创建保存顶点的列表
list< vertex *> r_list;

r_list.push_back(pr);另一件事:如果你的列表比你构造的顶点更多,那么它将指向一个无效的顶点。



例如:

  // global 
list< vertex *> r_list;

void some_function(void)
{
//创建顶点
vertex r = {WHITE,NULL,NULL}

//创建指向顶点结构的指针
vertex * pr =& r;

r_list.push_back(pr);
} //在这里,顶点r停止存在:列表现在包含一个
//无效指针。

一个解决方案是存储指向堆分配顶点的指针:

  // global 
list< vertex *> r_list;

void some_function(void)
{
//创建顶点
vertex * r = new vertex;
r-> color = WHITE;
r-> distance = 0;
r-> parent = 0;

r_list.push_back(r);
}

现在即使在函数之后列表指向一个有效的堆分配顶点。现在有一个问题,当你完成使用列表,你需要通过lsit并调用 delete 在每个元素。使用 Boost Pointer容器库 a>。



最好的方法是只保存顶点本身(而不是指向它们的指针):

  //创建一个列表来保存顶点
list< vertex> r_list;

//创建顶点
vertex r = {WHITE,NULL,NULL};

r_list.push_back(r);

如果给一个构造函数顶点,你甚至可以直接构造它们:

  struct vertex 
{
int color;
int distance;
char parent;

vertex(int _color,int _distance,char _parent):
color(_color),
distance(_distance),
parent(_parent)
{
}
};

//创建一个保存顶点的列表
list< vertex> r_list;

r_list.push_back(vertex(WHITE,NULL,NULL));

(这些已经超出您的问题)



首先,NULL通常只在处理指针时使用。由于 distance parent 不是指针,请使用 0 初始化它们,而不是 NULL

  //创建顶点
vertex r = {WHITE,0,0};

其次,使用常数 c $ c> #define

  #define NUM_VERTICES 8 //<  -  bad 
const int NumberVertices = 8; //< - good

最后,给你的枚举一个名字,

 枚举Color {WHITE,GREY,BLACK}; 

希望有这些帮助!


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);
}

解决方案

There are several things wrong here.

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.

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);

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.

For example:

// 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);
}

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)

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};

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 };

Hope these help!

这篇关于STL列出保存结构指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆