用户自定义销毁(免费)功能

问题描述:

这是我的第一个问题。我无法理解这个程序中的几行代码。用户自定义销毁(免费)功能

自定义销毁函数指针是我无法理解的。

我已经评论过“需要帮助#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://*.com/questions/840501/how -do-function-pointers-in-c-work) – Shahbaz

+0

你需要帮助,但是你的问题请澄清一下? – Tonmoy

对于问题#1

传递到链表上创建的参数destroypointer to a function。链接不知道如何销毁它保存的对象,从而释放内存。所以它需要一些来自外部的执行该操作的东西。因此,用户必须编写一个函数,该函数知道如何释放保存在列表中的对象的内存,并告诉链接列表在需要销毁节点时使用该函数。

指向函数的指针保存在列表变量destroy中。

对于问题2

的功能,你已经通过了以就被称为指针,并传递一个指向存储在当前节点中的数据,以释放它占用的内存。

这种技术被称为command or action pattern

  • #help1:=没有被调用;(它不仅局限于空中接力!)函数指针只分配给:在赋值list->destroy之后包含销毁函数的地址。
  • #HELP2:=现在的函数被调用:func(arg)是一个函数调用,所以是funcptr(arg),如果fncptr是一个函数指针类型
  • #HELP3:= memset(list, 0, sizeof(List));错误地假定一个NULL指针值由下式表示全零。它不需要。 (在大多数情况下是这样,但一个achitecture可能有NULL不同的表示)