【问题标题】:awkward behaviour of file reading in c program (SIGSEV signal)c程序中文件读取的尴尬行为(SIGSEGV信号)
【发布时间】:2014-12-26 08:13:15
【问题描述】:

我实现了一个程序,该程序应该使用 Prim 找到最小生成树。图的边缘在文件中进行了描述。

首先,程序读取这个文件并在数据结构中存储边。之后,它运行算法。这是完整的代码:

      #include <stdio.h>


    #include <stdlib.h>

      #define MAXVERTICES 1000
      #define INFINITY 99999
      #define TAILLEMAX 100

      struct vertex {
            int visited, predecessor;
            int dist;   // distance qui sépare ce noeud de la distance minimale d'un autre noeud
      };

      int treeEdge[MAXVERTICES][2], mstCost; // tableau des 'aretes' qui constituent l'arbre couvrant
      int graphEdge[MAXVERTICES][MAXVERTICES], nodeCount; // matrice d'adjacences (couts séparant chaque sommet des autres sommets)
      struct vertex node[MAXVERTICES];  // tableau de sommets numérotés de 1 à n

      /* construct the input graph */

      void buildGraph() {
            int source, dest, weight, test;
            char temp[TAILLEMAX];

        FILE* fichier = NULL;
        fichier = fopen("inst_v100.txt", "r");
        if (fichier != NULL)
        {
            fgets(temp, TAILLEMAX, fichier); // sauter ligne
            fscanf(fichier,"%s%d",temp,&nodeCount); // nbr de sommets
            fgets(temp, TAILLEMAX, fichier);
            fgets(temp, TAILLEMAX, fichier);

            while (1)
            {
                    test = fscanf(fichier,"%d%d%d",&source,&dest,&weight);
                    if(test==0)
                        break;
                    /* update weight of the edge */
                    graphEdge[source][dest] = weight;
                    graphEdge[dest][source] = weight;
                    fgets(temp, TAILLEMAX, fichier); // sauter ligne
            }
        }
        fclose(fichier);
        return;
  }



    /* all vertices are visited or not */
      int allVisited() {
            int i;
            for (i = 0; i < nodeCount; i++)
                    if (node[i].visited == 0)
                            return 0;
            return 1;
      }

      /* construct minimum spanning tree */
      int buildTree() {
            int i = 0, count = 0, currentNode, mindist;
            while (i < nodeCount) {
                    node[i].visited = 0;
                    node[i].predecessor = 0;
                    node[i].dist = INFINITY;
                    i++;
    }

        node[0].visited = 1;
        node[0].dist = 0;

        currentNode = 0;
        while (allVisited() == 0) {
                for (i = 0; i < nodeCount; i++) {  // pour le sommet courant, chercher la distance min qui le sépare de chaque sommet

                        /* Find the adjacent vertices and update the edge lenght */
                        if(graphEdge[currentNode][i] > 0 && node[i].visited == 0) {
                                if (graphEdge[currentNode][i] < node[i].dist) {
                                        node[i].predecessor = currentNode;
                                        node[i].dist = graphEdge[currentNode][i];
                                }
                        }
                }

                mindist = INFINITY;
                /* trouver l'arete avec le poids minimum */
                for (i = 0; i < nodeCount; i++) {
                        if (node[i].dist < mindist && node[i].visited == 0) {
                                mindist = node[i].dist;
                                currentNode = i;
                        }
                }
                /* Mark the vertex as visited - edge with min cost */
                node[currentNode].visited = 1;
                treeEdge[count][0] = node[currentNode].predecessor;
                treeEdge[count][1] = currentNode;

                /* calculate cost of MST */
                mstCost = mstCost + graphEdge[treeEdge[count][0]][treeEdge[count][1]];
                count++;
        }
        return count;
  }

  int main() {
        int i, count1;

        /* construct graph */
        buildGraph();
        count1 = buildTree();
        printf("MST is composed of below edges:\n");
        for (i = 0; i < count1; i++) {
                printf("%d<->%d\n", treeEdge[i][0], treeEdge[i][1]);
        }
        printf("\n");
        printf("Cost of Minimum Spanning Tree: %d\n", mstCost);
        return 0;
  }

尴尬的是,当执行开始时,程序会发送一个 SIGSEV 信号。

你能帮我找出我正在做的错误吗?提前致谢。

【问题讨论】:

  • "什么时候开始执行"???你不能想出一个更准确的描述吗???
  • 这意味着当我开始执行程序时,对不起我的英语不好,这就是为什么我不能有效地解释。 @SouravGhosh 我将添加一些有关文件内容的详细信息,我应该准确地说包含超过 4950 行。
  • gdb 是你的朋友。至少我们需要知道程序在哪里崩溃了。可能就像找不到文件一样简单,程序segfaulting in fclose(NULL)
  • gdb 说错误在这一行:treeEdge[count][0] = node[currentNode].predecessor;
  • 我看起来不够努力,但我看不到并检查了countnodeCount

标签: c segmentation-fault minimum-spanning-tree file-read


【解决方案1】:

问题解决了。

事实上,如果您仔细观察,我使用了 fgets 和 fscanf,这会导致歧义。 解决方案是使用 fgets(将读取的行存储在字符串中),然后使用 sscanf 从该字符串中获取所需的信息。

它给出了这样的东西:

    fgets(the_string, MAXLENGTH, file);
    sscanf(the_string,"%d",&number_wanted);

还是非常感谢你,希望我的回答对其他有同样问题的人有所帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-05
    • 1970-01-01
    • 2014-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多