簡體   English   中英

循環時鏈表中的分段錯誤?

[英]segmentation fault in a linked list while loop?

我正在嘗試在C中設置一個圖形。我使用用戶輸入嘗試了該圖形,並且它運行完美。 但是,我試圖實現從文件讀取。 最后的else語句是錯誤的出處,因為當我注釋掉它時,它可以毫無問題地進行編譯。 我已經對我認為存在問題的區塊發表了評論。 請讓我知道這個問題是否還有其他需要。

#include <stdio.h>
#include <stdlib.h>

struct node{
    int data;
    struct node* next;
};

//int counter and mainVertex would be used to determine if graph is connected.

// void graphConnection(){
// 
// 
// 
// 
// 
// 
// }


char* deblank(char* input)
{
    int i,j;
    char *output=input;
    for (i = 0, j = 0; i<strlen(input); i++,j++)
    {
        if (input[i]!=' ')
            output[j]=input[i];
        else
            j--;
    }
    output[j]=0;
    return output;
}


struct node *G[1000];
int counter = 0;
char *mainVertex;

void readingEachLine(){

  FILE * fp;
  char * line = NULL;
  size_t len = 0;
  ssize_t read;

  //Read file and exit if fail
  fp = fopen("test.txt", "r");
  if (fp == NULL)
      exit(EXIT_FAILURE);

  while ((read = getline(&line, &len, fp)) != -1) {
    line = deblank(line);
    int i = 0;
    struct node* cursor = malloc(sizeof(struct node));
    struct node* secondcursor = malloc(sizeof(struct node));
    struct node* tempitem;
    while(line[i] != '\n'){

      //If its the first of the line look into the array and set struct cursor to the corresponding
      //array position

      if (i == 0){
        mainVertex[counter] = line[0];
        int convertor = line[i] - '0';
        cursor = G[convertor];
        counter++;
      }
      //if its not the first, then set a struct with that number as data

      else{
        tempitem = malloc(sizeof(struct node));
        int convertor = line[i] - '0';
        tempitem->data = convertor;
        tempitem->next = NULL;
      }
      //if there is no element connected to the struct in array, connect the tempitem

      if (cursor->next == NULL){
        cursor->next = tempitem;
      }
      //If there are already connected elements, loop until the end of the linked list
      //and append the tempitem
      //ERROR: I GET SEGMENTATION FAULT FROM HERE. TRIED AFTER COMMENTING IT OUT

      else{
        secondcursor = cursor;
        while(secondcursor->next != NULL){
          secondcursor = secondcursor->next;
        }
        secondcursor->next = tempitem;
      }
      i++;
    }
    printf("\n");
  }
}

int main(void){
  for (int i = 1; i < 1000; i++)
  {
      G[i]= malloc(sizeof(struct node));
      G[i]->data = i;
      G[i]->next = NULL;
  }
  readingEachLine();
}

編輯:這是文本文件的外觀:

1 3 4
2 4
3 1 4
4 2 1 3

您的代碼有幾個misconceoptions:

  • 顯然,您最多可以有1,000個節點。 您有一個1,000個指向鏈接列表的頭指針的數組G 開始時不要為所有1,000個節點分配內存。 最初,所有列表都是空的,而空鏈接列表是沒有節點且頭為NULL
  • 在您的示例中, cursor用於迭代已經存在的指針,因此請不要為其分配內存。 如果您有這樣的代碼:

     struct node *p = malloc(...); // next use of p: p = other_node; 

    你不應該分配。 您將覆蓋p並失去分配內存的句柄。 並非所有指針都必須使用malloc初始化; 僅在創建節點時分配。

  • 如果您有9個以上的節點,那么刪除一行中的所有空格然后解析單個數字的想法將失敗。 (但是您可以容納1,000個節點。)不要嘗試自己解析數字。 有相應的庫函數,例如strtol
  • 目前尚不清楚mainVertex應該是什么。 分配給它時,只能使用一次。 您將其視為一個數組,但是它是一個初始化為NULL的全局指針。 取消引用它時,您會得到不確定的行為,這可能是您的細分錯誤的來源。

這是一個執行您想要做的程序。 (為簡單起見,它總是在頭插入節點,並且應該進行更多的分配檢查。)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

enum {
    maxNodes = 1000
};

struct node{
    int data;
    struct node* next;
};

struct node *G[maxNodes];
size_t nnode = 0;

int read_graph(const char *fn)
{
    FILE * fp;
    char * line = NULL;
    size_t len = 0;

    fp = fopen(fn, "r");
    if (fp == NULL) return -1;

    while (getline(&line, &len, fp) != -1) {
        char *p;
        char *end;
        int id;
        int n;

        id = strtol(line, &end, 10);
        if (end == line) continue;

        if (id < 1 || id > maxNodes) break;

        if (id > nnode) nnode = id;
        id--;

        p = end;
        n = strtol(p, &end, 10);

        while (p != end) {
            struct node *nnew = malloc(sizeof(*nnew));

            nnew->data = n - 1;
            nnew->next = G[id];
            G[id] = nnew;

            p = end;
            n = strtol(p, &end, 10);
        }
    }

    fclose(fp);
    free(line);

    return 0;
}

int main(void)
{
    if (read_graph("test.txt") < 0) {
        fprintf(stderr, "Couldn't gread raph.\n");
        exit(1);
    }

    for (int i = 0; i < nnode; i++) {
        struct node *p = G[i];

        if (p) {
            printf("%d:", i + 1);

            for (; p; p = p->next) {
                printf(" %d", p->data + 1);
            }

            puts("");
        }
    }

    for (int i = 0; i < nnode; i++) {
        struct node *p = G[i];

        while (p) {
            struct node *old = p;

            p = p->next;
            free(old);
        }
    }

    return 0;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM