2016-11-17 2 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. Нужно ли мне что-либо делать с превью в моей функции удаления? – CheetahBongos

+0

Почему вы не останавливаете свой цикл перед узлом, который нужно удалить? Потому что ты должен. Также поддерживайте указатель предыстории, или вы можете просто скопировать содержимое следующего узла и отделить его вместо определенного узла. –

ответ

1

Я изменил вашу функцию 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); 
} 
1

Вы говорите, беда с deleteAtPos. Но ваш код очень далек от SSCCE, поэтому я не хочу изолировать проблему для вас - вы должны это делать, и большую часть времени, в процессе изоляции, вы найдете ответ. Если нет, вы можете задать вопрос здесь.

Поэтому я просто перечислил то, что я вижу неправильно, с deleteAtPos, и, возможно, если вы исправите все из них, проблема исчезнет.

  1. Вы не обрабатывает ситуацию, когда *head является NULL, то список содержит 0 элементов. Это, несомненно, будет segfault.

  2. Вы не проверяете это pos >= 0.

  3. Вы неправильно обрабатываете случай, когда в вашем списке есть один элемент. Еще один секрет.

  4. Вы неверно обработане случая, когда pos является конечным в вашем списке. Еще один секрет.

Смежные вопросы