2016-11-17 12 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 

助けてください!あなたはトラブルがdeleteAtPosであると言っている

+1

最後のノードのロジックを確認してください。 Null、Current-> next = temp-> nextに値を設定します。それは間違っています –

+0

はい私はあまりにも思っています、私は多くの異なる方法を試みましたが、私はそれを動作させることができませんでした。私は実際にリストを逆向きに印刷しようとしています。それが私にseg faultを与え続けます。私は私の削除機能でprevで何かする必要がありますか? – CheetahBongos

+0

ノードを削除する必要がある直前にループを停止させるのはなぜですか?あなたはしなければならないから。 prevポインタも維持するか、次のノードの内容をコピーして、特定のノードの代わりにそのノードを細分することができます。 –

答えて

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

ありがとうございました。しかし、あなたのコードはSSCCEから非常に遠いので、私はあなたのために問題を分離したくありません。そうするべきです。ほとんどの場合、分離の過程で、あなたは答えを見つけるでしょう。そうでない場合は、ここに質問を投稿することができます。

したがって、私が見ることができるものはdeleteAtPosで間違っていますが、すべてを修正しても問題は消えてしまいます。

  1. *headがNULLの場合、リストには0個の要素があります。これは確かに失敗するだろう。

  2. これはチェックしていません。pos >= 0

  3. あなたのリストに1つの要素がある場合も正しく処理されていません。別のセグメンテーション。

  4. posがリストの最後である場合を正しく処理していません。別のセグメンテーション。

関連する問題