简体   繁体   中英

Segmentation fault when accessing a pointer's member function in a vector

For some reason I'm getting a segmentation fault; I'm using a vector of pointers, which point to a class object. Basically I need a node that has a vector of pointers to other nodes, in other to make a multigraph. Here's the relevant part of my code:

node.h:

#ifndef NODE_H
#define NODE_H

class node
{
public:
    string content()
    vector<node*> next;      //causing the error
    void add_arc(node a);

    string rna_frag;

#endif

node.cpp:

void node::add_arc(node a)
{
    node *b = &a;    //b->content() works fine here
    next.push_back(b);
}

string node::content()
{
    return rna_frag;
}

main.cpp:

int main()
{
    vector<node> nodes;
    node a;
    node b;
    node c;

    a.add_arc(b);
    a.add_arc(c);
    a.rna_string = "G";

    nodes.push_back(a);
    nodes.push_back(b);
    nodes.push_back(c);

    cout << nodes[0].content() << endl;    //prints "G", works fine
    cout << nodes[0].next.size() << endl;  // prints "2", works fine
    cout << nodes[0].next[0]->content() << endl;  //segmentation fault
    //cout << nodes[0].next->content() << endl;   //also segmentation fault
    //cout << nodes[0].next[0]->rna_frag << endl; //also segmentation fault
}

in this case, nodes[0]'s string is "G" and is pointing to 2 other nodes, so the first 2 couts are working perfectly. But when I access the vector's contents it just crashes and gives a segmentation fault error. Anyone know why?

In add_arc you are storing the address of the parameter a , which is then destroyed when the function exits - so you have undefined behaviour.

You're also copying nodes when you call nodes.push_back() , which is going to cause you a lot of grief.

You are going to need to either stop copying or write a proper copy constructor (and then follow the rule of 3, or 5).

With

void node::add_arc(node a)
{
    vertex *b = &a;    //b->content() works fine here
    next.push_back(b);
}

you add in next the pointer to an object that is destroyed exiting from the method ( a ).

Using it...

cout << nodes[0].next[0]->content() << endl;

crash!

Suggestion: transform next in a vector of nodes (not pointer of nodes)

If you do vector.push_back(a) the node in the vector is a copy (stored at a different memory adress). Moreoever your add_arc takes its parameter by value and the node you push into the vector is local to that function. Once this you leave the scope of this function dereferencing that pointer is undefined behaviour.

You should consider passing the argument by reference, or in that case even simpler a pointer to the node you want to add. However, also then you have to be aware that in your main this...

vector<node> nodes;
node a;
node b;

a.add_arc(b);

nodes.push_back(a);
nodes.push_back(b);

would not be what you want, because now a has b added as arc, while the second entry of the nodes vector is a copy of b . Maybe in that case it would be easier to use a vector<node*> nodes because you can copy pointers and they will still point to the same object.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM