向后打印双向链表分段错误

Doubly linked list segmentation fault printing backwards

我正在尝试删除特定位置的节点,但我一直收到分段错误 11。

我正在从文件中读取位置和值。

这是我的代码:

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

typedef struct node {
  float val;
  struct node *prev;
  struct node *next;
}node_t;

void printForward(node_t *head) {
  node_t *current = head;

  while (current != NULL) {
    printf("%.2f\n", current->val);
    current = current->next;
  }
}

void printBackward(node_t *head) {
  node_t *current = head;

  while (current->next != NULL) {
    current = current->next;
  }

  while (current != NULL) {
    printf("%.2f\n", current->val);
    current = current->prev;
  }
}


void deleteAtPos(node_t **head, int pos) {
  int i;
  node_t *current = *head;
  node_t *temp = NULL;

  if (pos == 0) {
    temp = (*head)->next;
    free(*head);
    (*head) = temp;
    (*head)->prev = NULL;
    return;
  }

    for (i = 0; i < (pos - 1); i++) {
      if (current->next != NULL) {
        current = current->next;
      }
    }

      temp = current->next;
      current->next = temp->next;
      free(temp);
}


// Fix insert at position
void insertAtPos(node_t **head, int pos, float val) {
  int i;
  node_t *newNode = malloc(sizeof(node_t));
  node_t *current = *head;
  newNode->val = val;

  if (pos == 0) {
    newNode->next = (*head);
    newNode->prev = NULL;
    (*head)->prev = newNode;
    (*head) = newNode;
    return;
  }

  for (i = 0; i < pos; i++) {
    if (current->next != NULL) {
      current = current->next;
    }
    else {
      printf("Node does not exist\n");
      break;
    }
  }

  current->prev->next = newNode;
  newNode->prev = current->prev;
  newNode->next = current;
  current->prev = newNode;
}

void addEnd(node_t **head, float val) {
  node_t *current = *head;
  node_t *newNode = malloc(sizeof(node_t));
  newNode->next = NULL;
  newNode->val = val;

  if (*head == NULL) {
    *head = newNode;
    newNode->prev = NULL;
    return;
  }

  while (current->next != NULL) {
    current = current->next;
  }
  current->next = newNode;
  newNode->prev = current;
}

int main(int argc, char *argv[]) {
  if (argc != 2) {
    printf("Error");
  }

  node_t *head = NULL;

  FILE *fp;
  int i = 0, x;
  float valLine1, valLine2, valLine3;
  char buffer[200], *token, *del = ",";
  float posVals[200], delPos[200];
  fp = fopen(argv[1], "r");

  fgets(buffer, sizeof(buffer), fp);
    token = strtok(buffer, del);
    while (token != NULL) {
      valLine1 = atof(token);
      addEnd(&head, valLine1);
      token = strtok(NULL, del);
    }

    printForward(head);
    printf("\n");


    del = ":,";
    fgets(buffer, sizeof(buffer), fp);
    token = strtok(buffer, del);
    while (token != NULL) {
      valLine2 = atof(token);
      posVals[i] = valLine2;
      token = strtok(NULL, del);
      i++;
    }

    for (x = 0; x < i; x += 2) {
      insertAtPos(&head, posVals[x + 1], posVals[x]);
    }
    printForward(head);

    fgets(buffer, sizeof(buffer), fp);
    i = 0;
    token = strtok(buffer, del);
    while (token != NULL) {
      valLine3 = atof(token);
      delPos[i] = valLine3;
      token = strtok(NULL, del);
      i++;
    }
    printf("\n");


    for (x = 0; x < i; x++) {
      deleteAtPos(&head, delPos[x]);
    }



    printForward(head);
    printf("\n");
    printBackward(head);

    fclose(fp);


}

问题出在我的 deleteAtPos 函数上,但我不知道为什么。

这是输出:

24.00
0.04
17.00
-200.10
34.60
0.00
Segmentation fault: 11

这是文件的内容:

17,32.5,12,0,34.6,-200.1,17,0.04,24
1:2,4.1:5,-12:4
3,5,0

请帮忙!

谢谢

你是说 deleteAtPos 有问题。但是你的代码离 SSCCE 很远,所以我不想为你隔离问题——你应该这样做,而且大多数时候,在隔离的过程中,你会找到答案。如果没有,您可以 post 在此处提问。

因此,我将只列出我能看到的 deleteAtPos 错误的地方,也许如果您修复所有这些问题,问题就会消失。

  1. 您没有处理 *head 为 NULL 的情况,列表有 0 个元素。这肯定会出现段错误。

  2. 您没有检查 pos >= 0

  3. 您也没有正确处理列表只有一个元素的情况。另一个段错误。

  4. 您没有正确处理 pos 是列表末尾的情况。另一个段错误。

我已经修改了你的 deleteAtPos() 函数,现在你可以在任何位置删除,你的 backward() 函数将打印正确的值。

void deleteAtPos(node_t **head, int pos) {
  int i;
  node_t *current = *head;
  node_t *temp = NULL;    

  if (pos == 0) {
    temp = (*head)->next;
    free(*head);
    (*head) = temp;
    (*head)->prev = NULL;
    return;
  }

    for (i = 0; i < (pos - 1); i++) {
      if (current->next != NULL) {
        current = current->next;
      }
    }


    temp = current;
    if(current->next==NULL)
    {
        current->prev->next = current->next;
    }
    else
    {
        current->prev->next = current->next;
        current->next->prev = current->prev;
    }

    free(temp);
}