C++ 为什么我在尝试编写图形时会出现分段错误?

C++ 为什么我在尝试编写图形时会出现分段错误?,c++,graph,structure,C++,Graph,Structure,我的任务是读取以下输入格式的图形: 并以这种格式输出 然而,当我运行我的程序时,我总是遇到分段错误。我想我的问题是在写图表的时候,但我似乎不知道为什么。有人能给我指一下正确的方向吗 更多信息:readGraph必须使用insertEdge插入边。 不管怎样,每行读三个数字都很诱人。在最后一行,只有一个数字将被成功读取。但程序往往会被修改,而且,只要工作量不大,就做好修改的准备是个好主意。如果更改程序,使图形后有更多输入,该怎么办?您不希望readGraph读入图形后面的内容 编写readGr

我的任务是读取以下输入格式的图形:

并以这种格式输出

然而,当我运行我的程序时,我总是遇到分段错误。我想我的问题是在写图表的时候,但我似乎不知道为什么。有人能给我指一下正确的方向吗

更多信息:readGraph必须使用insertEdge插入边。 不管怎样,每行读三个数字都很诱人。在最后一行,只有一个数字将被成功读取。但程序往往会被修改,而且,只要工作量不大,就做好修改的准备是个好主意。如果更改程序,使图形后有更多输入,该怎么办?您不希望readGraph读入图形后面的内容

编写readGraph,使其不依赖于仅包含0的行作为输入中的最后一项。这很容易做到。读第一个数字,在读下两个之前检查一下

 struct Edge
    {
        int vertex1;
        int vertex2;
        int weight;

        Edge()
        {
            vertex1 = 0;
            vertex2 = 0;
            weight = 0;
        }
    };

    struct Graph
    {
        int numOfVertices;
        int numOfEdges;
        Edge*   edges;
        int sizeOfArray;

        Graph(int n, int e)
        {
            numOfVertices = n;
            numOfEdges = 0;
            sizeOfArray = e;
            edges = new Edge[e];
        }
    };

    //Inserts an edge between vertices u and v, of weight w, into graph g.
    void insertEdge(int u, int v, int w, Graph* g)
    {
        Edge e;
        e.vertex1 = u;
        e.vertex2 = v;
        e.weight = w;
        g->edges[g->numOfEdges] = e;
        g->numOfEdges++;

    }

    //Reads vertices, edges, and weight from the input
    //and allocates a graph in the heap with enough room for e edges.
    Graph* readGraph(int e)
    {
        int numberOfVertices, edge;
        scanf("%i", &numberOfVertices);
        Graph* g = new Graph(numberOfVertices, e);
        int u, v, w;
        while(scanf("%i", &edge) != 0)
        {

            scanf("%i%i%i", &u, &v, &w);
            insertEdge(u,v,w,g);
        }
        return g;
    }

    //Writes graph g by listing the number of vertices and the number of edges.
    void writeGraph(const Graph* g)
    {
        printf("There are %i vertices and %i edges", g->numOfVertices, g->numOfEdges);
        printf("Vertices        Weight");
        for(int i = 0; i < g->numOfEdges; i++)
        {
            printf(" %i %i      %i", g->edges[i].vertex1, g->edges[i].vertex2, g->edges[i].weight);
        }

    }

    int main()
    {  

        int maxEdges = 1000;
        Graph* g = readGraph(maxEdges);
        writeGraph(g);
        return 0;
    }
struct-Edge
{
int顶点1;
int顶点2;
整数权重;
边缘()
{
顶点1=0;
顶点2=0;
权重=0;
}
};
结构图
{
整数顶点;
int-numOfEdges;
边*边;
int-sizeOfArray;
图(整数n,整数e)
{
n=n;
numOfEdges=0;
sizeOfArray=e;
边=新边[e];
}
};
//将权重为w的顶点u和v之间的边插入到图g中。
无效插入边缘(整数u、整数v、整数w、图形*g)
{
边e;
e、 顶点1=u;
e、 顶点2=v;
e、 重量=w;
g->边[g->numOfEdges]=e;
g->numOfEdges++;
}
//从输入中读取顶点、边和权重
//并在堆中分配一个有足够空间容纳e边的图。
图形*readGraph(int e)
{
整数个顶点,边;
scanf(“%i”和numberoftextexts);
图*g=新图(顶点数,e);
国际u,v,w;
while(scanf(“%i”、&edge)!=0)
{
scanf(“%i%i%i”、&u、&v、&w);
插入(u、v、w、g);
}
返回g;
}
//通过列出顶点数和边数写入图g。
无效写图(常量图*g)
{
printf(“有%i个顶点和%i条边”,g->numoftexts,g->numOfEdges);
printf(“顶点权重”);
对于(inti=0;inumOfEdges;i++)
{
printf(“%i%i%i”,g->edges[i]。顶点1,g->edges[i]。顶点2,g->edges[i]。权重);
}
}
int main()
{  
int maxEdges=1000;
Graph*g=读取图形(MaxEdge);
笔迹(g);
返回0;
}

我看不出你的代码有什么问题,但我可能是瞎子。除非如此,您可以使用gdb进行调试。15分钟的时间:

或者你可以使用一些工具,比如Valgrind:,


我祝你一切顺利

多亏了GDB中一些好的旧打印语句,我才找到了答案。在readGraph中,scanf首先扫描edge变量并存储该变量。因此,读取的下一个数字将不是实际的第一个数字,从而导致无限循环(分段错误),因为根据输入,0将作为图形的一部分读取,并且以后再也找不到。只需将扫描更改为scanf(“%i%i”、&v和&w);在insertEdge()中使用已经读取的u将正确读取图形。

我认为应该将引用传递给指针,而不仅仅是指针,因为这样,在函数中所做的任何更改都不会对主函数产生影响。所以函数签名应该是
void insertEdge(intu,intv,intw,Graph*&g)
@Nuttracker好吧,为什么不声明该类的成员函数或只传递对该类的引用呢?不幸的是,我已经预先添加了不允许更改的函数标题,因此它需要使用我当前拥有的签名来实现。请注意,
Graph
类正在泄漏内存。你至少需要一个析构函数。