还是在看redis3.0源码的时候,遇到如下问题:
这个时候我们回到list这个结构体的设计上面
首先我们必须要注意的是函数名字就可以看成指针地址。
所以下面我们写一个简单的实例看一下具体的用法:
#include <stdio.h>
#include <stdlib.h>typedef struct listNode {void *value;struct listNode *next;
} listNode;typedef struct list {listNode *head;void (*free)(void *ptr);
} list;void customFreeFunction(void *ptr) {printf("Freeing value: %s\n", (char *)ptr);free(ptr); // 假设值是动态分配的字符串
}void listRelease(list *myList) {listNode *current = myList->head;listNode *next;while (current) {next = current->next;// 如果设置了free函数,使用它来释放节点值if (myList->free) myList->free(current->value);free(current); // 释放节点结构current = next;}free(myList); // 释放链表结构
}int main() {// 创建链表并分配第一个节点list *myList = malloc(sizeof(list));//这里让free指向了一个函数地址myList->free = customFreeFunction; // 设置释放函数// 创建节点并赋值myList->head = malloc(sizeof(listNode));myList->head->value = malloc(20); // 为节点值分配空间snprintf(myList->head->value, 20, "Hello, Redis!"); // 设置值// 释放链表listRelease(myList);return 0;
}
大致相当于是做了一个套娃操作:1.我给head里面的value分配了一片空间,用来存放字符串。像上面这样的字符串空间大小就是20个空间大小。
2.我们想要释放这片空间,是先把包含head里面的value的这个结点传给listRelease
3.然后listRelease里面在去调用了free指向的函数进行释放,同时传入了value这个地址值。不考虑数据类型转换直接释放。
大致就这样。