2015-01-09 60 views
0
#include <stdio.h> 
#include <stdlib.h> 
//why does this work with pointers thought they made a copy? 
//am i freeing memory correctly and well? 
//Something wrong with freeing 
struct Node{ 

    struct Node* next; 
    int data; 

}; 
void newNode(struct Node* trans, int val) 
{ 
    if(trans!=NULL) 
    { 
     while(trans->next!=NULL) 
     { 
      trans=trans->next; 
     } 
     //next is null create heap memory 
     trans->next=malloc(sizeof(struct Node)); 
     //checking to see if memory is created 
     if(trans->next==NULL) 
     { 
      printf("This has failed"); 
     } 
     //put in data 
     trans->next->data=val;  
     //next is null 
     trans->next->next=NULL; 
    } 

} 
void printList(struct Node* head) 
{ 
    if(head!=NULL) 
    { 
     struct Node* current; 
     current=head; 
     while(current->next!=NULL) 
     { 
      //print that current nodes data 
      printf("list is: %d\n",current->data); 
      current=current->next; 
     } 
    printf("last element is: %d\n",current->data); 

    } 
    else 
    { 
     printf("list is empty!"); 
    } 

} 
int removeLastNode(struct Node* trans) 
{ 

    //return -1 if its a empty list 
    int val=-1; 
    if(trans!=NULL) 
    { 
     /*have to access trans->next->next cause you are freeing trans->next->next and getting its val 
     then you want to set tran->next to NULL! 
     */ 
     while(trans->next->next!=NULL) 
     { 
      trans=trans->next; 
     } 
     //at end of the list? 
     val=trans->next->data; 
     //free the heap 
     free(trans->next); 
     //next points to null 
     trans->next=NULL; 

    } 
    return val; 
} 
//LOOK AT ME! 
void freeList(struct Node* root) 
{ 
    struct Node* temp; 
    struct Node* current; 
    current=root; 
    while(current->next!=NULL) 
    { 
     temp=current; 
     //going to the next one 
     current=current->next; 
     //freeing previous 
     free(temp);  
    } 
    //Am I really freeing the last one? 
    free(current); 

    root->next=NULL; 
    root=NULL; 

} 
void addingHundred(struct Node* trans) 
{ 
    int i; 
    for(i=0;i<100;i++) 
    { 
     newNode(trans,i); 
    } 
} 

int main() 
{ 
    struct Node* root; 
    //create heap mem for root 
    root=malloc(sizeof(struct Node)); 
    root->next=NULL; 
    root->data=10; 
    //traversal pointer 
    struct Node* trans; 
    //setting to point to root 
    trans=root; 
    //adding a new node.. 
    newNode(trans,8); 
    printf("value of trans after function call: %p\n",trans); 
    newNode(trans,12); 
    //value does not change 
    printf("value of trans after function call: %p\n",trans); 
    addingHundred(trans); 

    //printing the list 
    printList(root); 

    int storage; 
    //removing last node 
    storage=removeLastNode(trans); 
    //returns the last nodes value 
    printf("value removed: %d\n",storage); 
    printList(root); 
    freeList(root); 
    printList(root); 

    return 0; 
} 

我有幾個關於我上面寫的代碼的問題。一般的概念問題在main我用這個結構做一個struct Node* tran我調用newNode函數,它接受一個struct Node*。現在我把tran作爲參數我不通過tran的地址。在這種情況下,函數newNode只會創建一個tran的值的副本,並且在函數調用之後,函數中的任何操作都將被撤消?通過鏈接列表的函數指針

我注意到這與一個打印語句至少tran的值在newNode函數調用後沒有改變。我想知道的是,我的鏈接列表如何擴展,並且正在跟蹤?在這種情況下,傳遞tran的值是否會起作用,因爲它最初指向根值的堆內存,然後簡單地遍歷堆中的內存,但實際上並未改變內存的內容?

如果是的話,以更改列表中的一個節點的值,我將不得不通過&trans作爲參數,但如果我只是遍歷列表添加在最後一個節點,我可以通過tran作爲論據?

我的另一個問題是我不相信我的freeList(struct Node* a)功能工作正常。因爲當我釋放root然後打印它時,它會爲我打印一個垃圾值,而應該打印「列表爲空」或打印垃圾是否導致其訪問內存我不擁有?

最後,這裏有人批評我的代碼是「最終用戶應用程序代碼」。我對編碼還不熟悉,而且我不確定上面的代碼是否格式不正確,或者說是否是最終用戶應用程序代碼。如果有人解釋如何避免編寫「最終用戶應用程序代碼」,我將非常感激。

+0

這是一個很大的問題。 – gsamaras 2015-01-09 23:24:12

+0

我不確定如何在沒有解釋的情況下清楚地問清楚。 – Nightlife 2015-01-09 23:26:15

+0

代碼應該總是檢查malloc(和系列)返回的值以確保操作成功 – user3629249 2015-01-09 23:55:41

回答

2

您沒有按值傳遞trans,您正在傳遞一個指向結構體Node的指針,因此將永遠不會創建副本。

你說

我沒有通過移植的

地址,這是絕對錯誤的,你是路過,其實這一點。

的價值不會改變,因爲你沒有修改該指針,在每次通話後newNodetrans指針指向正好給它的調用之前做了同樣的地址,在價值所以沒有變化應觀察

當你調用newNode一個新的節點添加到列表的尾部,所以如果你真的穿越,你會看到所有的值列表,下面的代碼將打印值

struct Node *node; 
for (node = root ; node != NULL ; node = node->next) 
    printf("value %d @ %p\n", node->val, node); 

有你應該看到每個節點的地址,它的價值

free並不意味着0內存,而不是你free它,操作系統,這就像你放棄了內存的所有權在該地址,如果有對的義務10的記憶,會有一個巨大的表現擊中由於那。

如果您需要根據您的代碼,以使列表,empty,你應該確切地調用freeList()

root = NULL; 

我固定的代碼


此言後做:您的freeList函數在末尾有一個free(current),它將釋放最後一個節點,所以我刪除它,也修正了一些風格的東西,搞得printList()功能更可讀

#include <stdio.h> 
#include <stdlib.h> 
//why does this work with pointers thought they made a copy? 
//am i freeing memory correctly and well? 
//Something wrong with freeing 
struct Node{ 

    struct Node* next; 
    int data; 

}; 
void newNode(struct Node* trans, int val) 
{ 
    if (trans != NULL) 
    { 
     while (trans->next != NULL) 
      trans = trans->next; 
     /* next is null create heap memory */ 
     trans->next=malloc(sizeof(struct Node)); 
     /* checking to see if memory is created */ 
     if(trans->next == NULL) 
      printf("This has failed"); 
     /* put in data */ 
     trans->next->data = val; 
     /* next is null */ 
     trans->next->next = NULL; 
    } 
} 
void printList(struct Node* head) 
{ 
    struct Node *node; 

    if (head == NULL) 
     printf("empty list\n"); 
    for (node = head ; node != NULL ; node = node->next) 
     printf("list is: %d\n", node->data); 
} 

int removeLastNode(struct Node* trans) 
{ 
    int val = -1; 
    /* return -1 if its a empty list */ 
    struct Node *node; 
    struct Node *last; 
    if (trans == NULL) 
     return -1; 
    /* 
    * have to access trans->next->next cause you are freeing trans->next->next and getting its val 
    * then you want to set tran->next to NULL! 
    */ 
    node = trans; 
    last = node->next; 
    while (last->next != NULL) 
    { 
     node = node->next; 
     last = node->next; 
    } 
    trans = node; 
    node = node->next; 

    /* at end of the list? */ 
    val = node->data; 
    /* free the heap */ 
    free(node); 
    /* next points to null */ 
    trans->next = NULL; 

    return val; 
} 

//LOOK AT ME! 
void freeList(struct Node* root) 
{ 
    struct Node* temp; 
    struct Node* current; 

    current = root; 
    while (current != NULL) 
    { 
     temp=current; 
     /* going to the next one */ 
     current=current->next; 
     /* freeing previous */ 
     free(temp); 
    } 
} 
void addingHundred(struct Node* trans) 
{ 
    int i; 
    for (i=0 ; i < 100 ; i++) 
     newNode(trans, i); 
} 

int main() 
{ 
    struct Node* root; 
    int   storage; 

    //create heap mem for root 
    root = malloc(sizeof(struct Node)); 

    root->next=NULL; 
    root->data=10; 

    //adding a new node.. 
    newNode(root, 8); 
    newNode(root, 12); 

    addingHundred(root); 

    //printing the list 
    printList(root); 


    //removing last node 
    storage = removeLastNode(root); 

    //returns the last nodes value 
    printf("value removed: %d\n", storage); 
    printList(root); 

    freeList(root); 

    root = NULL; 

    printList(root); 

    return 0; 
} 

我這樣做是爲了你最後的評論,在你的問題的身體。我不明白,但當然你可以改善你的代碼格式。不要害怕使用空格字符,編譯器無論如何都會忽略它們(當然除了字符串字面量外)。