内存管理器一般来说都是基于池的,分配时从池中取,释放时再还给池,通常会有一条链表专门保存释放后的内存节点,这样下次再分配时直接从该链表头取就可以了,链表的操作很简单,我就不多赘述了。在Python中,这个操作没有显示的用链表实现,而是用了点小技巧,为便于说明,我写了个简单的实例,相信大家都能看明白,如下:
- #include <stdio.h>
- #include <stdlib.h>
- static void *free_list;
- static void *
- my_alloc(int size)
- {
- void *ptr;
-
- if (free_list) {
- ptr = free_list;
- free_list = *(void **) ptr;
- }
- else
- ptr = calloc(1, size);
- return ptr;
- }
- static void
- my_free(void *ptr)
- {
- *(void **) ptr = free_list;
- free_list = ptr;
- }
- static void
- my_show(void)
- {
- void *ptr = free_list;
-
- while (ptr != NULL) {
- printf("%p ", ptr);
- ptr = *(void **) ptr;
- }
-
- printf("\n");
- }
- #define N 5
- int main(void)
- {
- int i;
- void *data[N];
- printf("The first time :\n");
- for (i = 0; i < N; i++) {
- data[i] = my_alloc(8);
- printf("%p ", data[i]);
- }
- printf("\n\n");
-
- for (i = 0; i < N;i++) {
- my_free(data[i]);
- my_show();
- }
-
- printf("The second time :\n");
- for (i = 0; i < N; i++) {
- data[i] = my_alloc(8);
- printf("%p ", data[i]);
- }
-
- printf("\n\n");
- for (i = 0; i < N;i++) {
- my_free(data[i]);
- my_show();
- }
- return 0;
- }
不知大家是否注意到,这里从头到尾都没有链表,但是事实上仍是链表,只不过这里是通过指针的“跳跃”来实现链表互连的,即类似于用 ptr = *ptr 转向链表的下一个节点。另外,如果显式地用链表串联各空闲节点,对于每个空闲节点都要next指针,其实有点多余了。而这里next指针直接在空闲节点内存中存储了,反正这些内存都已经释放了,闲着也是闲着,还不如顺便保存一下next嘛,是吧。
阅读(4262) | 评论(5) | 转发(0) |