【问题标题】:How to copy a vector of lists?如何复制列表向量?
【发布时间】:2013-12-21 02:43:18
【问题描述】:

在我的程序中,我需要将 private 数据结构复制(甚至使用)到完全不同类的 .cpp 文件中。目前我什至只是简单地远程访问它时遇到了麻烦,当我尝试打印它时它会出现故障。这是我的类的简化版本,带有数据结构:

class Graph
{
private:
    class Edge
    {
    public:
        Edge(string vertex, int weight)
        {
            m_vertex = vertex;
            m_weight = weight;
        }
        ~Edge(){}
        string m_vertex;
        int m_weight;
    };
    vector< list<Edge> > adjList;
public:
    Graph();
    ~Graph();
    vector < list < Edge > > get_adjList(){return adjList;}
    //Other functions....

};

在一个完全不同的功能中,我尝试这样做......

void MinPriority::testPrint(string targetVertex) //FOR TESTING PURPOSES SO FAR (FAILS TO WORK) SEGMENTATION FAULT NO MATTER WHAT
{

    targetVertex = "A";
    Graph graph;
    graph.adjList = graph.get_adjList(); //adjList is our empty container based on the array of linked lists
    /*1*/cout << graph.get_adjList()[0].front().m_vertex << " TEST!" << endl;

    /*2*/cout << "The very first vertex is: ";
    if(graph.adjList.size() == 0)
        cout << "NULL<!>" << endl;
    else cout << graph.adjList[0].front().m_vertex << endl;
}

请注意,我将 targetVertex 设置为“a”,因此我的程序可以编译,因为我的 makefile 中包含 -Werror(分配所需)。当我注释掉 /*1*/ 并运行到 /*2*/ 时,输出将始终为 @987654326 @,无论数据结构中有多少元素。在/*1*/,我尝试打印出由函数get_adjList() 返回的对象,但读取此内容时出现段错误:

Exception: STATUS_ACCESS_VIOLATION at eip=611298C5
eax=0A0A0A0A ebx=01010101 ecx=20050884 edx=F5F5F5F5 esi=20058488 edi=20060000
ebp=0028A8D8 esp=0028A8D0 program=C:\cygwin\home\Ryan\311\P5Dec16\Graph.exe, pid 5612, thread main
cs=0023 ds=002B es=002B fs=0053 gs=002B ss=002B
Stack trace:
Frame     Function  Args
0028A8D8  611298C5  (20058400, 0000000A, 20058488, 610FD3CA)
0028A938  6115F91F  (0028D41C, 61187720, 0028A958, 0043455D)
0028A988  61137BF7  (0028D41C, 20058400, 00000001, 20058488)
0028A9B8  61137CD5  (20058400, 00000001, 20058488, 61187720)
0028A9D8  610D6745  (00449240, 20058400, 20058488, 004493C4)
0028AA68  004439BA  (004493C0, 6123D5FC, 004452B4, 0028AAA0)
0028AB08  00402756  (0028AC20, 0028ABB0, 20010100, 004011C1)
0028AC68  00401583  (00000001, 0028AC90, 20010100, 612757A2)
0028ACF8  6100763A  (00000000, 0028CD78, 61006C50, 00000000)
End of stack trace
Segmentation fault (core dumped)

简而言之,我想知道这个堆栈跟踪是什么(我以前遇到过段错误,但我从未见过这个)。我想知道如何从#include "Graph.h" 的其他文件中的类Graph 中正确访问数据结构。我也不确定如何在testPrint(); 中复制我的对象。为什么这在Graph.cpp 中可以完美运行?

void Graph::set_array(string vertex)
{
    //increment vector size by 1 and insert a new Edge object into the vector of linked lists
    cout << "ADDING " << vertex << " TO VECTOR" << endl;
    adjList.resize(adjList.size() + 1);
    adjList[adjList.size() - 1].push_back(Edge(vertex, 0));
}

【问题讨论】:

  • Graph的默认构造函数是做什么的?
  • 里面什么都没有Graph::Graph() { }析构函数也是空的。
  • 您应该使用-g 标志编译以具有调试符号,这样您将有一个更易于理解的回溯。您还可以通过“常量引用”(而不是按值)传递对象以避免复制。
  • 应该 get_adjList 真的返回一个全新的副本,而不是参考?

标签: c++ oop data-structures vector copy


【解决方案1】:
Graph graph;

正如你所说,Graph 的默认构造函数什么都不做。所以此时,graph.adjList 为空。

graph.adjList = graph.get_adjList();

这是一个毫无意义的声明,它从自身的副本中分配给graph.adjList。以前是空的,现在还是空的。

cout << graph.get_adjList()[0].front().m_vertex << " TEST!" << endl;

这会尝试访问graph.adjList(的副本)的第一个元素。但是graph.adjList 是空的(即它没有第一个元素),所以这是未定义的行为。它可能是也可能不是您的段错误的原因,但它肯定是一个必须解决的问题,然后才能进行任何进一步有用的调试。

【讨论】:

  • 图结构需要包含什么?列表的向量?
  • @user3040019:恐怕我不明白这个问题,或者至少没有足够的信息来解决你的问题。
  • 对不起,我的意思是图形“构造函数”需要包含什么/
  • @user3040019:要使cout 语句有效,至少需要将一个元素(一个list&lt;Edge&gt;)放入adjList,可能通过push_back,或emplace_backresize。您还尝试访问列表的第一个元素,因此还需要将至少一个元素(一个 Edge)放入您刚刚添加的列表中。
  • 我将添加检查以确保数据结构中没有元素。我正在考虑让我的构造函数像这样:Graph::Graph() { new vector &lt; list &lt; Edge &gt; &gt;; } 我的想法是这将创建一个新向量,我们可以使用在 graph.h 中声明的向量的引用。我不太确定它是否会起作用。
猜你喜欢
  • 1970-01-01
  • 2021-04-17
  • 2013-01-24
  • 1970-01-01
  • 2011-03-28
  • 1970-01-01
  • 2020-03-19
  • 2015-03-28
  • 2019-11-09
相关资源
最近更新 更多