在STL和元素插入中动态分配列表

时间:2017-03-05 13:14:00

标签: c++ list c++11 stl

以下代码应该读取图形中的多个节点,然后读取一定数量的边缘,这些边缘将在动态分配的相邻节点列表中引入。由于某种原因,程序在status:{{status}} 中调用add_edge()函数时停止,IDE(也称为cb)打开read_graf()的主文件。任何人都可以指出这个问题吗?谢谢!

以下是代码:

stl_list

这是一个输入:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<list>
#define grafMAX 101

FILE *fin = fopen("grafin.txt","r");
FILE *fout = fopen("grafout.txt","w");

struct Graf{
    int nrV;
    std::list <int> *ad;
};

void init_graf(Graf g, int nr){
    g.nrV = nr;
    g.ad = new std::list <int> [g.nrV];//(std::list <int> *)malloc(g.nrV * sizeof(std::list <int>));
}

void add_edge(Graf g, int n1, int n2){
    g.ad[n1].push_back(n2);
    g.ad[n2].push_back(n1);
}

inline int min(const int a, const int b){
    if(a < b)
        return a;
    return b;
}

void read_graf(Graf g){
    int n,m;
    fscanf(fin,"%d%d",&n,&m);
    init_graf(g,n);
    while(m){
        int x,y;
        fscanf(fin,"%d%d",&x,&y);
        add_edge(g,x,y);
        --m;
    }
}

2 个答案:

答案 0 :(得分:1)

您将Graf值传递给函数。这意味着所有更改都是对您传递的参数的副本进行的。原件没有变化。

如果您希望更改在函数外部可见,则应将Graf的引用传递给void init_graf(Graf& g, int nr)

答案 1 :(得分:1)

在开始之前,这是两种C编码风格的奇怪组合,只需要输入少量C ++即可访问List类。这绝不是一个好主意。您的大多数代码都是用C语言编写的,因此您应该使用通过malloc获得的C数组。如果要使用C ++ List Class,则应使用C ++类重写此程序,并包含文件和结构。

关于你的问题...

当您调用init_graf时,您将按值传递Graf G,因此当init_graf返回时,init_graf完成的任何初始化都将丢失。您需要在C中通过引用传递它,以便您可以更新它。

稍后,当您调用add_edge时,g仍然未初始化,因此字段&#34; ad&#34;仍未初始化,因此g.ad [n1]将取消引用错误的指针,导致异常并且您的程序将暂停:

void add_edge(Graf g, int n1, int n2){
    g.ad[n1].push_back(n2);
    g.ad[n2].push_back(n1);

要解决这个问题,init_graf应该得到一个指向Graf结构的指针,同样add_edge也应该得到一个指向g的指针。这是你的解决方案,删除了类列表(使其成为一个真正的C程序)。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
// #include<list>
#define grafMAX 101

FILE *fin = fopen("grafin.txt","r");
FILE *fout = fopen("grafout.txt","w");

struct Edge {
     int startNode;
     int endNode; 
};

struct Graf{
    int  nrV;      
    int  edgeCount; // Added to keep track of number allocated
    Edge *ad;
};

void init_graf(Graf *g, int nr){
    g->nrV       = 0;
    g->edgeCount = nr; 
    g->ad = malloc(graphMax*sizeof(Edge));
}

void add_edge(Graf *g, int n1, int n2){
    // Check array bound before adding a new edge
    if (g->nrV < g->edgeCount) {
       // Add the edge to the edge array and increment nrV
       g->ad[g->nrV].startNode = n1;
       g->ad[g->nrV].endNode   = n2;
       g->nrV++;
    }
}

inline int min(const int a, const int b){
    if(a < b)
        return a;
    return b;
}

void read_graf(Graf *g){
    int n,m;
    fscanf(fin,"%d%d",&n,&m);
    init_graf(g,n);
    while(m){
        int x,y;
        fscanf(fin,"%d%d",&x,&y);
        add_edge(g,x,y);
        --m;
    }
}

如果你真的想使用C ++,那么Bo建议使用&amp;通过引用传递Graf参数很好,但是我建议你重新构建程序以使用类而不是结构并使用C ++头而不是C头(例如cstdio而不是stdio.h)