2016-05-14 2 views
1

私はちょうどCとリンクリストについて学んでいます。私はいくつかの大きな問題があります。cのリンクリストの最後の項目を削除する際の問題

私は、次のコードしている:私はJavaScriptからArray.prototype.popに似て動作するようになっているポップを実行すると

#include <stdio.h> 
#include <stdlib.h> 
struct people { 
    int age; 
    char *name; 
    struct people * next; 
}; 
typedef struct people people; 

void count(people array) { 
    people *current=malloc(sizeof(people)); 
    current = &array; 
    int count = 0; 
    while(current){ 
     count++; 
     printf("name %s\n",current->name); 
     printf("age %d\n",current->age); 
     current=current->next; 
    } 
    printf("%d\n", count); 
    free(current); 
} 
void push(people *array){ 
    people * new=malloc(sizeof(people)); 
    people *last=malloc(sizeof(people)); 
    new->age=300; 
    new->name="baz"; 
    new->next=NULL; 
    last=array; 
    while(last->next){ 
     last=last->next; 
    } 
    last->next=new; 
// free(new); 
} 
void pop(people *array){ 
    people * last=malloc(sizeof(people)); 
    last=array; 
    while(last->next){ 
     //get the last element in the list 
     last=last->next; 
    } 
// free the last element 
    free(last); 
} 
int main(int argc, char** argv) { 
    people person = { 
     .name = "foo", 
     .age = 25 
    }; 
    person.next = malloc(sizeof (people)); 
    person.next->age = 26; 
    person.next->name = "bar"; 
    person.next->next = NULL; 
    //push into the list 
    push(&person); 
    //count after pushing 
    count(person); 
    //remove last 
    pop(&person); 
    //at this count i get just the age 0 but the name was not removed and still counts 3 
    count(person); 
    return 0; 
} 

を。
最後のnextの名前は "baz"で、年齢は300です。この最後の構造体を削除する代わりにこのコードを実行した後、年齢は0になります。

無料のポインタは割り当てられていませんmallocで。

+2

最後のone-before-lastは無効なメモリを指しています。 free()は指定されたメモリチャンクをメモリアロケータに返すだけで、ポインタは有効なメモリに設定されません。 – GeorgeAl

+1

@GeorgeAlコメントに加えて、たくさんのメモリがリークします。現在のものと最後のものが自分の記憶を得たら、ポインタを他のアドレスに割り当てることによってそれをドロップするだけです。 – Andreas

+0

@GeorgeAlどのように私は自由に動作しない場合、割り当てられたメモリピースを解放するのですか? – nikoss

答えて

0

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

typedef struct people { 
    int age; 
    char *name; 
    struct people * next; 
} people; 


people *new_people(const char *name, int age){ 
    people *node = malloc(sizeof(people)); 
    char *copy_name = malloc(strlen(name)+1); 
    strcpy(copy_name, name); 

    node->age = age; 
    node->name = copy_name; 
    node->next = NULL; 
    return node; 
} 

void free_people(people *p){ 
    free(p->name); 
    free(p); 
} 

void count(people *array) { 
    people *current = array; 
    int count = 0; 

    while(current){ 
     count++; 
     printf("name %s\n", current->name); 
     printf("age %d\n", current->age); 
     current = current->next; 
    } 
    printf("%d\n", count); 
} 

void push(people **array, people *addNode){ 
    if(*array == NULL){ 
     *array = addNode; 
     return ; 
    } 

    people *last = *array; 
    while(last->next){ 
     last = last->next; 
    } 
    last->next = addNode; 
    //return length; 
} 

people *pop(people **array){ 
    if(*array == NULL) 
     return NULL; 

    people *last = *array; 
    people *prev = NULL; 
    while(last->next){ 
     prev = last; 
     last=last->next; 
    } 
    if(prev != NULL) 
     prev->next = NULL; 
    else 
     *array = NULL; 
    return last; 
} 

int main(void) { 
    people *array = NULL; 
    push(&array, new_people("foo", 25)); 
    push(&array, new_people("bar", 26)); 
    push(&array, new_people("baz", 300)); 

    count(array); 
    people *baz = pop(&array); 
    free_people(baz); 
    count(array); 

    people *bar = pop(&array); 
    free_people(bar); 
    people *foo = pop(&array); 
    free_people(foo);//free_people(pop(&array)) 

    return 0; 
} 
-2

あなたは、独自のロジックを使用する場合:

//use double pointer here, and send the head of the list 
void pop(people **array) { 
    people *last = *array; //asign like this 
    while(last) { // not last->next 
     last = last->next; 
    } 
    last = NULL; 
    free(last); 
} 

//call like this 
pop(&list); 

を、これは動作するはず今

+0

これはdoesn '右に見える。 ITYM 'while(last = * array){array =&last-> next; } 'と' last = NULL; 無料(最後); 'も間違っています。 – wildplasser

+1

これは* array =&last-> next; *?あなたは投票する前に自分のコードを見ることさえなかった.... –

+1

[私はそれを提出する前にあなた自身のコードを読んでいないと思う]あなたのwhileループの後、最後はNULLです。それは違いない。次に、NULLに設定します。それからあなたはそれを解放する。そして:はい、私は間違いを犯しました: 'while((last = * array)&& last-> next){array =&last-> next; } – wildplasser

-1

問題がvoid count(people array)で、current=current->next;が割り当てられることになる、ということですwhileループで。だから、pop-関数でlast-> nextがNULLに代入されるようにする必要があります。

私はにあなたのポップアップ機能を変更:あなたが「最後」から「配列」のアドレスを割り当てる必要があり、ポップ機能で

void pop(people *array){ 

    people * last=malloc(sizeof(people)); 

    while(array->next){ 
     last=array; 
     array=array->next; 
     if(array->next){ 
      //get the last element in the list 
      last=last->next; 
     }else{ 
      break; 
     }                        
    } 
    last->next=NULL; 
    array=last; 
} 

、その後、「array->次に「配列」を指します'

プログラムがwhileループからブレークすると、last->next=NULL;array=last;を実行して、最後の構造体が正常であることを確認できます。

関連する問題