在向量中访问指针的成员函数时出现分段错误

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

本文关键字:分段 错误 函数 成员 向量 访问 指针      更新时间:2023-10-16

由于某种原因,我遇到了分段错误;我使用的是一个指针向量,它指向一个类对象。基本上,我需要一个节点,它有一个指向其他节点的指针向量,在其他节点中创建一个多重图。这是我代码的相关部分:

节点.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
}

在这种情况下,nodes[0]的字符串是"G",并且指向另外两个节点,因此前两个cout工作得很好。但当我访问矢量的内容时,它会崩溃,并给出分割错误。有人知道为什么吗?

add_arc中,您存储参数a的地址,然后在函数退出时销毁,因此您有未定义的行为。

当您调用nodes.push_back()时,您也在复制节点,这会给您带来很多悲伤。

您需要停止复制或编写一个正确的复制构造函数(然后遵循3或5的规则)。

使用

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

next中添加指向从方法(a)退出时被销毁的对象的指针。

使用它…

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

崩溃!

建议:在节点的向量(而不是节点的指针)中转换next

如果执行vector.push_back(a),则向量中的节点是一个副本(存储在不同的内存地址)。无论怎样,add_arc都会按值获取其参数,并且推送到向量中的节点是该函数的局部节点。一旦这样,你就离开了这个函数的作用域,去引用那个指针就是未定义的行为。

您应该考虑通过引用传递参数,或者在这种情况下,更简单的是通过指向要添加的节点的指针来传递参数。然而,你也必须意识到,在你的主要。。。

vector<node> nodes;
node a;
node b;
a.add_arc(b);
nodes.push_back(a);
nodes.push_back(b);

不会是您想要的,因为现在a已经将b添加为arc,而节点向量的第二个条目是b副本。也许在这种情况下,使用vector<node*> nodes会更容易,因为你可以复制指针,它们仍然指向同一个对象。