2013-09-29 29 views
1

這是我的第一個問題。我無法理解這個程序中的幾行代碼。用戶自定義銷燬(免費)功能

自定義銷燬函數指針是我無法理解的。

我已經評論過「需要幫助#1並需要幫助#2」,我需要幫助的代碼。

任何幫助將不勝感激,我會非常感謝任何能夠幫助我理解這些代碼的人。

#ifndef LIST_H 
#define LIST_H 
#include <stdio.h> 

typedef struct _ListElmt 
{ 

    void *data; 
    struct ListElmt *next; 

} ListElmt; 
typedef struct _List 
{ 

    int size; 
    int (*match)(const void *key1, const void *key2); 
    void (*destroy)(void *data); 

    ListElmt *head; 
    ListElmt *tail; 

} List; 

void list_init(List *list, void (*destroy)(void *data)); 

void list_destroy(List *list); 

int list_ins_next(List *list, ListElmt *element, const void *data); 

int list_rem_next(List *list, ListElmt *element, void **data); 

int list_size(const List *list); 

ListElmt *list_head(const List *list); 

ListElmt *list_tail(const List *list); 

int list_is_head(const ListElmt *element); 

int list_is_tail(const ListElmt *element); 

void *list_data(const ListElmt *element); 

ListElmt *list_next(const ListElmt *element); 
#endif 

,這裏是list.c

#include <stdlib.h> 
#include <string.h> 
#include "List.h" 

/* Need Help #1: The destroy function pointer is called here when the list is initialized and I need some explanation on how this works */ 

void list_init(List *list, void (*destroy)(void *data)) 
{ 

    list->size = 0; 
    list->destroy = destroy; 
    list->head = NULL; 
    list->tail = NULL; 

    return; 
} 

void list_destroy(List *list) 
{ 

    void *data; 

    while (list_size(list) > 0) 
    { 

    if (list_rem_next(list, NULL, (void **) &data) == 0&& list->destroy != NULL) 
    { 

     list->destroy(data); 

     /* Need Help #2: The above line - how this works. I have no idea how this works because I haven't seen any code like that before. Also kindly let me know if this is recursion or not.*/ 
    } 
    } 
    memset(list, 0, sizeof(List)); 
    return; 
} 

int list_ins_next(List *list, ListElmt *element, const void *data) 
{ 

    ListElmt *new_element; 

    if ((new_element = (ListElmt *) malloc(sizeof(ListElmt))) == NULL) // not yet understanded 
    return -1; 

    new_element->data = (void *) data; 

    if (element == NULL) 
    { 
    if (list_size(list) == 0) 
     list->tail = new_element; 

    new_element->next = list->head; 
    list->head = new_element; 
    } 

    else 
    { 
    if (element->next == NULL) 
     list->tail = new_element; 

    new_element->next = element->next; 
    element->next = new_element; 
    } 

    list->size++; 
    return 0; 
} 

int list_rem_next(List *list, ListElmt *element, void **data) 
{ 

    ListElmt *old_element; 

    if (list_size(list) == 0) 
    return -1; 

    if (element == NULL) 
    { // Handle removal of the head 

    *data = list->head->data; 
    old_element = list->head; 
    list->head = list->head->next; 

    if (list_size(list) == 1) 
     list->tail = NULL; 
    } 

    else 
    { // Handle removal from somewhere else 

    if (element->next == NULL) 
     return -1; 

    *data = element->next->data; 
    old_element = element->next; 
    element->next = element->next->next; 

    if (element->next == NULL) 
     list->tail = element; 
    } 

    free(old_element); 

    list->size--; 
    return 0; 
} 
+1

的可能重複【如何用C的工作做函數指針?](http://stackoverflow.com/questions/840501/how -do-function-pointers-in-c-work) – Shahbaz

+0

你需要幫助,但是你的問題請澄清一下? – Tonmoy

回答

3

對於問題#1

傳遞到鏈表上創建的參數destroypointer to a function。鏈接不知道如何銷燬它保存的對象,從而釋放內存。所以它需要一些來自外部的執行該操作的東西。因此,用戶必須編寫一個函數,該函數知道如何釋放保存在列表中的對象的內存,並告訴鏈接列表在需要銷燬節點時使用該函數。

指向函數的指針保存在列表變量destroy中。

對於問題2

的功能,你已經通過了以就被稱爲指針,並傳遞一個指向存儲在當前節點中的數據,以釋放它佔用的內存。

這種技術被稱爲command or action pattern

0
  • #help1:=沒有被調用;(它不僅侷限於空中接力!)函數指針只分配給:在賦值list->destroy之後包含銷燬函數的地址。
  • #HELP2:=現在的函數被調用:func(arg)是一個函數調用,所以是funcptr(arg),如果fncptr是一個函數指針類型
  • #HELP3:= memset(list, 0, sizeof(List));錯誤地假定一個NULL指針值由下式表示全零。它不需要。 (在大多數情況下是這樣,但一個achitecture可能有NULL不同的表示)