创建类的一个点后的c++段错误

标签 c++ segmentation-fault

我有一个抛出分段的 C++ 代码段错误:

图的矩阵表示

0100

0010

1011

0000

节点,标签:1,列索引:0

/C/Program Files/NetBeans 8.1/ide/bin/nativeexecution/dorun.sh:第 33 行:13140 段错误 sh "${SHFILE}"

代码片段:

     void graph::shortest_path(std::vector<std::vector<int>> &_matrix) {
    //1) initialize not visited nodes 
    int num_of_nodes = _matrix.size();
    std::queue<Node> unvisited;
    std::queue<Node> visited;

    for (int i = 0; i < num_of_nodes; i++) {
        unvisited.push(Node(i + 1));
    }



    //while unvisited is NOT empty
    while (!unvisited.empty()) {


        //2) pop/remove from unvisited & are there adjacent neighbors 
        Node node = unvisited.front();
        std::cout << "Node, label:" << node.getLabel() << ",column index:" << node.getLabel() - 1 << endl;
        vector<int>& columnVector = _matrix[node.getLabel() - 1];
        //nodes integer label 
        int label = 0;
        //loop add adjacency list * back pointers
        for (int c = 0; c < columnVector.size(); c++) {
            //if there are actual connections, then adjacency matrix value at C NOT equal INT_MAX
            if (columnVector[c] != INT_MAX) {
                //create a node & add to current nodes adjacency list 
                Node * adj = new Node(c+1); 
                adj->setPrev(node);
                node.addToAdjacenyList(*adj);
                //also set the prev reference 

            }
        }//end loop add adjacency list * back pointers


        //3) for each node calculate the total weight or cost back to the start & select the min 
        for (int i = 0; i < node.getAdjacenyList()->size(); i++) {
            cout << node.getAdjacenyList()->at(i).getLabel() << ",";


        }
        cout << endl;

        //keep track of visited nodes 
        visited.push(node);
        //since this node was visited remove/pop it from unvisited 
        unvisited.pop();


    }

}

但是,当我在没有 new 关键字的情况下实例化时,我没有遇到任何段错误:

//loop add adjacency list * back pointers
        for (int c =0; c<columnVector.size(); c++)
        {
            //if there are actual connections, then adjacency matrix value at C NOT equal INT_MAX
            if (columnVector[c]!=INT_MAX)
            {
                //create a node & add to current nodes adjacency list 
                //Node * adj = new Node(c+1); 
                //adj->setPrev(node);
                node.addToAdjacenyList(Node(c+1));
                //also set the prev reference 

            }
        }//end loop add adjacency list * back pointers

好的输出:

图的矩阵表示

0100

0010

1011

0000

节点,标签:1,列索引:0 2、 节点,标签:2,列索引:1 3、 节点,标签:3,列索引:2 1,3,4, 节点,标签:4,列索引:3

**Here is the Node class:**

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

#include "Node.h"
#include <vector>

Node::Node()
{

}

Node::Node(int label):_label(label)
{

}

Node::~Node()
{
    Node::_adjacency_list->clear(); 
}

void Node::setLabel(int val)
{
    _label = val; 
}

int Node::getLabel()
{
    return _label; 
}

void Node::setWeight(int val)
{
    _weight = val; 
}

int Node::getWeight()
{
    return _weight; 
}

int Node::getDistance()
{
    return _distance;
}

void Node::setDistance(int val)
{
    _distance = val; 
}

/*
 * std::vector<Node>* getAdjacenyList();
    void addToAdjacenyList(const Node& node);
 */

std::vector<Node>* Node::getAdjacenyList()
{
    std::vector<Node>* point = &*_adjacency_list;
    return point; 
}

void Node::addToAdjacenyList(const Node& node)
{
    _adjacency_list->push_back(node);
/*
 * 
 *  Node* getPrev();
    void  setPrev(const Node& node); 
 */
}

Node* Node::getPrev()
{
     Node* point = &*_prev;
     return point; 
}

void Node::setPrev(const Node& n)
{
    *_prev = n; 
}

为什么会出现段错误以及如何解决?

谢谢

最佳答案

void Node::setPrev(const Node& n)
{
    *_prev = n; 
}

_prev 从未指向 dereferencing it 之前的有效内存位置并将 n 复制到其中。取消引用无效指针会调用可怕的 Undefined Behaviour .复制到无效内存也是未定义的行为,很可能是导致段错误的原因。

可能你需要的是

void Node::setPrev(Node * n)
{
    _prev = n; 
}

但这可能会在其他地方引发潜在的不良事件链,因为邻接表也存储拷贝。需要进行重大的重新设计。

立即有回声

Node* Node::getPrev()
{
     Node* point = &*_prev;
     return point; 
}

&*_prev; 取消对指针的引用并立即再次获取地址。如果 _prev 指向有效内存,则最终结果没有任何用处。如果 _prev 未指向有效内存,而事实并非如此,则 *_prev 的结果未定义。

Node* Node::getPrev()
{
     return _prev; 
}

更安全,但让接收者有责任在尝试使用之前确保接收到的内容有效。

关于创建类的一个点后的c++段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49455987/

相关文章:

xamarin - 在 Xamarin.IOS 中执行 native 代码时收到 SIGSEGV

c++ - 带有 XML 的 TCP 消息结构

c++ - 将纹理添加到二维元素

c++ - 如何将两个值相乘并以原子方式存储结果?

c - 根据大小写字母对字符串进行冒泡排序

c - 程序查找图的两个给定顶点之间是否存在路径

c++ - 段错误但数组对象没有越界 (C++)

c++ - 如果我在 Qt 中包含一个小部件数组,为什么会出现段错误?

c++ - 派生类的大小

c++ - 如何使用 boost::python 从流畅的界面公开属性?