Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在复制的std::list中转储_C++_List_Stl_Gdb_Circular List - Fatal编程技术网

C++ 在复制的std::list中转储

C++ 在复制的std::list中转储,c++,list,stl,gdb,circular-list,C++,List,Stl,Gdb,Circular List,我有一个图形类,看起来像: class Graph { public: typedef unsigned int size_type; typedef std::list<size_type> Neighbours; protected: size_type m_nodes_count, m_edges_count; public: Graph(size_type nodes_count = 0) : m_nodes_cou

我有一个图形类,看起来像:

class Graph {
  public:
    typedef unsigned int size_type;
    typedef std::list<size_type> Neighbours;

  protected:
    size_type m_nodes_count, m_edges_count;

  public:
    Graph(size_type nodes_count = 0) :
      m_nodes_count(nodes_count), m_edges_count(0) {}

    virtual bool is_edge(size_type from, size_type to) = 0;
    virtual Neighbours neighbours(size_type node) = 0;

    virtual Graph& add_edge(size_type from, size_type to) = 0;
    virtual void delete_edge(size_type from, size_type to) = 0;

    size_type nodes_count() { return m_nodes_count; }
    size_type edges_count() { return m_edges_count; }

    virtual ~Graph() {}
};

class AdjList : public Graph {
  private:
    typedef std::list<size_type> Row;
    std::vector<Row> m_list;

  public:
    AdjList(size_type nodes_count) : Graph(nodes_count) {
      m_list.resize(nodes_count);
    }

    AdjList(const AdjList& g) : AdjList(g.m_nodes_count) {
      for (int i = 0; i < nodes_count(); i++)
        std::copy(g.m_list[i].begin(), g.m_list[i].end(), std::back_inserter(m_list[i]));
    }

    virtual bool is_edge(size_type from, size_type to) override {
      return std::find(m_list[from].begin(), m_list[from].end(), to) != m_list[from].end();
    }

    virtual Graph& add_edge(size_type from, size_type to) override {
      if (!is_edge(from, to) && !is_edge(to, from)) {
        m_list[from].push_back(to);
        m_list[to].push_back(from);
        m_edges_count++;
      }

      return *this;
    }

    virtual void delete_edge(size_type from, size_type to) override {
      m_list[from].remove(to);
      m_list[to].remove(to);
      m_edges_count--;
    }

    virtual Neighbours neighbours(size_type node) {
      return m_list[node];
    }
};

如何解决这个问题?

我认为问题出在复制构造函数上,只需执行以下操作:

AdjList(const AdjList& g) : AdjList(g.m_nodes_count) {
    m_list = g.m_list ; 
}

操作符=()
方法应该使用
g.m_list
具有的相同节点创建一个新的
向量。

gdb
可能会被实现细节所迷惑。例如,旧版本作为循环列表实施。在
列表
对象中,只有一个名为
\M\u节点的
指针。构造函数将最终节点元素的内部
\u M_下一个
指针与
\u M_节点
本身相等

std::list
的标准库实现之所以使用此循环实现,是为了避免最后一个元素出现特殊情况(例如,它们也可以使用带有
nullptr
下一个指针的sentinel元素)。马特·奥斯特恩对此有一个很好的解释(但该链接当前指向一个已损坏的文件,请参阅)

此循环实现解释了为什么
g.neights()
gdb
输出具有重复模式
[0]=2、[1]=1、[2]=4294956560、/*etcetera*/
。值4294956560只是
std::list
的内部
\u M_节点
变量的内存地址,因此如果
gdb
只执行simnple指针跟踪,它将变得混乱。请注意,它小于
2^32
,也就是说,您可能正在为32位编译它


您可能应该在系统上标准库的
标题中验证这一点。
gdb
的错误报告也可能是正确的。

什么是
邻居
(它似乎是一个typedef,但要确定)另外,是否可能是gdb漂亮打印机的一些不寻常之处?如果运行将结果赋给局部变量的代码,它会产生相同的结果吗?那么它会很好地打印出来。谢谢但是它仍然不能解决我的工作:/但是谢谢。好吧,如果它在赋值后正确打印,可能是GDB中的一个错误,返回值的析构函数在打印之前被执行,导致垃圾数据。你能给出初始化图形的代码吗?一直到
g.neights(0)
调用,这让我想知道为什么在这种情况下,上面的std::list实例输出可以工作……谁知道呢,调试器可能会限制显示和截断多少元素。
AdjList(const AdjList& g) : AdjList(g.m_nodes_count) {
    m_list = g.m_list ; 
}