2016-11-17 74 views
0

我想删除特定位置的节点,但我一直得到分段错误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 

请帮帮忙!

谢谢

+1

检查你最后一个节点的逻辑。你将把值放在Null,Current-> next = temp-> next。这是错的 –

+0

是的,我也这么认为,我尝试了许多不同的方式,但我无法使它工作。我实际上试图向后打印列表,这就是不断给我一个seg故障。我是否需要在删除功能中使用prev做任何事情? – CheetahBongos

+0

为什么你不需要在需要删除的节点之前停止你的循环?因为你必须。维护prev指针也可以复制下一个节点的内容,并删除该节点而不是特定的节点。 –

回答

1

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

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

你说的麻烦是deleteAtPos。但是你的代码离SSCCE很远,所以我不想为你隔离问题 - 你应该这样做,大多数情况下,在隔离过程中,你会找到答案。如果没有,你可以在这里发布问题。

因此,我只列出我可以看到的东西与deleteAtPos错误,也许如果你解决所有这些问题,问题就会消失。

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

  2. 您并未检查pos >= 0

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

  4. 您没有正确处理这种情况,其中pos是列表的结尾。另一段错误。