2015-01-12 55 views
0

我的程序管理結構鏈表。免費的結構....我不知道我是否正確

這裏是我的STRUC:

typedef struct wagon wagon; 
typedef struct wagon{ 
    wagon *next; 
    marchandise_ptr *liste; 
    double volume_courant; 
}train_ptr; 

當貨車*接下來是一個指向我的鏈接列表的下一個「細胞」,marchandise_ptr *列表是一個指向另一個鏈表。要釋放我strucure,我已經着手如下:

在INT主要():

train_ptr *train=creer_un_train(...)//so train is the beginning of my linked list 
liberer_train(&train); 

我的職責是:

創建一個 「馬車」

wagon *creer_wagon(marchandise_ptr *liste,double volume_courant){ //it creates a wagon 
    assert(volume_courant>=0); 
    wagon *wag=malloc(sizeof(wagon)); 
    if(wag==NULL) 
     return NULL; 
    wag->next=NULL; 
    wag->volume_courant=volume_courant; 
    wag->liste=liste; 
    return wag; 
} 

添加在我的鏈式列表的末尾創建的「旅行車」:

train_ptr *ajouter_wagon_a_la_fin_du_train(train_ptr *train,double volume_courant, marchandise_ptr *liste){ 
    wagon *wag=creer_wagon(liste,volume_courant); 
    if(wag==NULL) 
     return NULL; 
    if(train==NULL) 
     train=wag; 
    else{ 
     train_ptr *wag_current=train; 
     while(wag_current->next!=NULL) 
      wag_current=wag_current->next; 
     wag_current->next=wag; 
     } 
    return train; 
} 

創建一個火車:

train_ptr *creer_un_train(unsigned int nombre_de_wagons,marchandise_ptr *liste){ 
    assert(nombre_de_wagons>=0); 
    int i; 
    train_ptr *train=NULL; 

    for(i=0;i<nombre_de_wagons;i++){ 
     train=ajouter_wagon_a_la_fin_du_train(train,rand()%10,liste); 
     if(train==NULL) 
      return NULL; 
     } 
    return train; 
} 

免費火車:

void liberer_train(train_ptr **train){ 
    train_ptr *p_current = *train; 
    while(p_current!=NULL){ 
       *train = p_current->next; 
       p_current->next=NULL; 
       free(p_current->liste); 
       free(p_current); 
       p_current = *train; 
    } 
} 

P.S:清單當然是一個指針鏈表的beginnig:

typedef struct marchandise marchandise; 
typedef struct marchandise{ 
    double volume; 
    double volume_total; 
    char nom; 
    marchandise *suivant; 
}marchandise_ptr; 

感謝您的關注! (並對不起我的英語,我不是母語......:D)

+2

您可以使用valgrind來搜索內存泄漏。 – tumdum

+0

我不明白'聽'是什麼?它指向的地方 – Gopi

+0

如果'p_current-> liste'是另一個鏈表,那麼'free(p_current-> liste)'將只釋放根目錄,指向另一個鏈表(也包含結構體) –

回答

1

從你的creer_wagon函數看來,liste似乎不應該被liberer_train函數釋放,因爲它沒有被分配由creer_wagon功能。

按照這個邏輯,在那裏你調用creer_wagon功能應該負責liste成員,因爲你將在調用函數的範圍內有效的指針給它,你的風險的雙重freeliste的成員。

如果每個train僅需要有一個refrence到liste,但並不需要修改它,你可以像這樣定義

typedef struct wagon{ 
    wagon *next; 
    const marchandise_ptr *liste; 
    double volume_courant; 
}train_ptr; 

這將防止意外試圖修改或freeliste成員的結構。

這種設計是有道理的,如果許多列車可能指向同一個liste,但它增加了struct wagon用戶的responsabilities,因爲他們應該照顧的內存管理,爲liste成員。如果是這種情況,我推薦使用const限定符。

在我看來,這是一種有效的推理方法,可以確定liste是否由您分配。

我建議你修復liberer_train功能這樣

void liberer_train(train_ptr **train) { 
    train_ptr *p_current = *train; 
    train_ptr *suivant = NULL; 
    while (p_current != NULL) { 
     suivant = p_current->next; 
     free(p_current);   
     p_current = suivant; 
    } 
    /* make the pointer NULL, so it's not a dangling pointer in the caller function anymore. */ 
    *train = NULL; 
} 

而且,我建議你換

typedef struct wagon train_ptr; 

typedef struct wagon *train_ptr; 

typedef struct wagon train; 

例如,因爲後綴_ptr讓人想到在train_ptr x;x是一個指針,雖然它不是。

相關問題