如何使用二维嵌套向量修复分割错误

问题描述 投票:1回答:2

我从gitHub的一个调整列表中编写了一个简单的图形调整矩​​阵。

第一个是调整列表,第二个是Adj矩阵。

第一个效果很好。但是第二个是错误的int Num,它代表第一个int numOfVertices的顶点编号。它的种子像“ int Num”一样成为只读变量。它崩溃为Process finished with exit code 11

我一直在Wiki中找到“细分默认值”,原因有4个,其中之一是试图修改只读内容变量。

然后我取消对Adj矩阵的构造函数中的“ Num”进行修改。效果很好。

但是我不知道为什么第一个很好但是第二个错了?以及如何解决呢?因为我需要修改Num的值...

调整列表代码

#ifndef ALTHGORITHM_GRAPH_ADJ_LIST_H
#define ALTHGORITHM_GRAPH_ADJ_LIST_H
#include <iostream>
#include <vector>
#include <queue>
namespace graph_adj_list {
    template <class dataType>                                 // Type of data vertex will hold
    class Graph {
        int numOfVertices;                                      // number of vertices.
        struct Vertex;                                          // forward declaration of vertex structure
        struct Node {                                           // linkedlist for mapping edges in the graph
            Vertex * vertexPtr;                                   // points to the vertex to which the edge is adjecent
            Node * next;                                          // points to the next edge belonging to same vertex
        };
        enum visitedState{                                      // Enum representing visited state of vertex
            WHITE,                                                // not yet visited
            GRAY,                                                 // being visited
            BLACK                                                 // visited
        };
        struct Vertex {
            visitedState state;                                   // state of vertex, visited/being visited/done
            dataType data;                                        // the template data
            Node * list;                                          // Pointer to all edges (linkedlist)
        };

        std::vector<Vertex> vertices;                           // vector of all vertices.
  //private methods
        Node * getNode( Vertex * );                             // allocate and initialize a newnode for the adj list.
        void insertAtEnd( Node * & , Vertex * );                // insert at the end of adjacency list of vertex.
        void deleteAllAfter( Node * );                          // delete the adjacency list of the vertex.
  public:
        Graph() = default;                                      // Default constructor
        Graph(std::vector<dataType> &); 
        ~Graph();
}
  template <typename dataType>
    typename Graph<dataType>::Node *
    Graph<dataType>::getNode(Vertex * v)                // allocate and initialize a newnode for the adj list.
    {
        Node * newNode = new Node;
        newNode->vertexPtr = v;
        newNode->next = nullptr;
        return newNode;
    }
  template <typename dataType>
    void Graph<dataType>::insertAtEnd( Node * & node, Vertex * v)  // insert at the end of adjacency list of vertex.
    {
        Node *newNode = getNode(v);
        if ( node == nullptr ) {
            node = newNode;
        } else {
            Node * temp = node;
            while( temp->next != nullptr ) {
                temp = temp->next;
            }
            temp->next = newNode;
        }
    }
    template <typename dataType>
    void Graph<dataType>::deleteAllAfter( Node * node )                  // delete the adjacency list of the vertex.
    {
        Node * nextNode;
        while( node != nullptr ) {
            nextNode = node->next;
            delete(node);
            node = nextNode;
        }
    }


   template <typename dataType>
    Graph<dataType>::Graph(std::vector<dataType> & values)              // Non default constructor, takes a vector of vertices data
            : numOfVertices(values.size()),
              vertices(numOfVertices)
    {
        for ( int i = 0; i < numOfVertices; ++i ) {
            vertices[i].data = values[i];
            vertices[i].list = nullptr;
            vertices[i].state = WHITE;
        }
    }

    template <typename dataType>
    Graph<dataType>::~Graph()
    {
        for( int i = 0; i < numOfVertices; ++i ) {
            deleteAllAfter(vertices[i].list);
        }
    }
} //end of namespace graph

Adj矩阵代码

#ifndef ALTHGORITHM_GRAPH_ADJ_MATRIX_H
#define ALTHGORITHM_GRAPH_ADJ_MATRIX_H
#include <iostream>
#include <vector>
namespace graph_adj_matrix {
    template<typename T>
    class Graph {
        int Num ;
        enum visitedState {
            NO_VISIT,
            VISITING,
            VISITED
        };
        struct vertex {
            T data;
            visitedState state;
        };

        std::vector<std::vector<int>> Matrix;
        std::vector<vertex> matrix_list;

    public:
        Graph() = default;
        Graph(std::vector<T> &);
        ~Graph();
        void setMatrix(size_t index1, size_t index2);
        void display();
    };


    template<typename T>
    Graph<T>::Graph(std::vector<T> &values) :
                            Num(values.size())
                            ,matrix_list(Num){
        for (typename std::vector<T>::size_type i = 0; i < Num; ++i)
        {
            matrix_list[i].data = values[i];
            matrix_list[i].state = NO_VISIT;
        }
        for (typename std::vector<T>::size_type i = 0; i < Num; ++i)
            for (typename std::vector<T>::size_type j = 0; j < Num; ++j)
                Matrix[i].push_back(0);
    }

    template<typename T>
    void Graph<T>::setMatrix(size_t index1, size_t index2) {
        for (size_t i = 0; i < Num; ++i) {
            if (i == index1 || i == index2) {
                for (size_t j = 0; j < Num; ++j) {
                    if (((i == index1) && (j == index2)) || ((i == index2) && (j == index1))) {
                        Matrix[i][j] = 1;
                        break;
                    }
                }
                break;
            }
        }
    }

    template<typename T>
    void Graph<T>::display() {
        for (size_t i = 0; i < Num; ++i) {
            for (size_t j = 0; j < Num; j++)
                std::cout << Matrix[i][j] << " ";
            std::cout << std::endl;
        }
    }

    template <typename T>
    Graph<T>::~Graph() {}
}
#endif //ALTHGORITHM_GRAPH_ADJ_MATRIX_H

Cpp:

#include "Graph_Adj_List.h"
#include "Graph_Adj_Matrix.h"

int main() {


    std::vector<std::string> myVec{"ABC","DEF","GHI","ZZZ"};


    graph_adj_list::Graph<std::string> myGraph(myVec);



    graph_adj_matrix::Graph<std::string> myGraph_matrix(myVec);



}

我已经调试了程序

    graph_adj_list::Graph<std::string> myGraph(myVec);

运作良好。但是

    graph_adj_matrix::Graph<std::string> myGraph_matrix(myVec);

停在

#ifndef _LIBCPP_CXX03_LANG

template <class _Tp, class _Allocator>
inline _LIBCPP_INLINE_VISIBILITY
void
vector<_Tp, _Allocator>::push_back(value_type&& __x)
{
    if (this->__end_ < this->__end_cap())
    {
        __RAII_IncreaseAnnotator __annotator(*this);
        __alloc_traits::construct(this->__alloc(),
                                  _VSTD::__to_raw_pointer(this->__end_),
                                  _VSTD::move(__x));
        __annotator.__done();
        ++this->__end_;
    }
    else
        __push_back_slow_path(_VSTD::move(__x));
}

[1635至1653的向量标头行中的函数。调试器报告此

Exception = EXC_BAD_ACCESS (code=1, address=0x8)
this = {std::_11::vector<int,std::_1::allocator> * |0x0 } NULL

当我输入设置```Matrix [i] .push_back(0)'的主体时,它将崩溃错误的条件。

c++ multidimensional-array clion exit-code segment
2个回答
1
投票

以下是您的代码,经过短暂的尝试:

处理完成,退出代码为11

可能可能意味着您的程序遇到了信号11(SIGSEGV,又名分段错误)

我的猜测:您忘了初始化Matrix,所以Matrix[i].push_back(0);导致未定义的行为,幸运的是,在分割错误中出现了结果集。

Edit:您可以使用向量构造函数std::vector<std::vector<int>>(Num, std::vector<int>(Num));轻松初始化内部向量。这将创建一个具有Num个整数的向量的Num个副本的向量。


1
投票

解决了@churill提出的问题后:

我尚未编译您的代码,但我认为问题出在以下几行:

Matrix[i][j] = 1;

在这种情况下,Matrix[i]vector<int>,但您从未为其保留容量,因此Matrix[i][j]正在写入受保护的/未分配的内存,从而导致段故障。

以足够的容量初始化“内部”向量(全部为Matrix[i]),然后查看是否可以解决段错误。

© www.soinside.com 2019 - 2024. All rights reserved.