双向链表分段故障打印向后

时间:2016-11-17 04:15:00

标签: c file doubly-linked-list

我正在尝试删除特定位置的节点,但我一直遇到分段错误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

请帮忙!

谢谢

2 个答案:

答案 0 :(得分:1)

你说问题出在deleteAtPos。但是你的代码离SSCCE很远,所以我不想为你隔离问题 - 你应该这样做,而且大部分时间,在隔离过程中,你会找到答案。如果没有,您可以在此处发布问题。

因此,我只会列出我可以看到的deleteAtPos错误的内容,如果你解决了所有问题,问题就会消失。

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

  2. 您没有检查pos >= 0

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

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

答案 1 :(得分:1)

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

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);
}