Chinaunix首页 | 论坛 | 博客
  • 博客访问: 191991
  • 博文数量: 27
  • 博客积分: 725
  • 博客等级: 上士
  • 技术积分: 347
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-04 09:01
文章分类

全部博文(27)

文章存档

2012年(15)

2011年(12)

分类: C/C++

2012-04-13 10:13:29

内存管理器一般来说都是基于池的,分配时从池中取,释放时再还给池,通常会有一条链表专门保存释放后的内存节点,这样下次再分配时直接从该链表头取就可以了,链表的操作很简单,我就不多赘述了。在Python中,这个操作没有显示的用链表实现,而是用了点小技巧,为便于说明,我写了个简单的实例,相信大家都能看明白,如下:

  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. static void *free_list;

  4. static void *
  5. my_alloc(int size)
  6. {
  7.     void *ptr;
  8.     
  9.     if (free_list) {
  10.         ptr = free_list;
  11.         free_list = *(void **) ptr;
  12.     }
  13.     else
  14.         ptr = calloc(1, size);

  15.     return ptr;
  16. }

  17. static void
  18. my_free(void *ptr)
  19. {
  20.     *(void **) ptr = free_list;
  21.     free_list = ptr;
  22. }

  23. static void
  24. my_show(void)
  25. {
  26.     void *ptr = free_list;
  27.     
  28.     while (ptr != NULL) {
  29.         printf("%p ", ptr);
  30.         ptr = *(void **) ptr;
  31.     }
  32.     
  33.     printf("\n");
  34. }

  35. #define N 5

  36. int main(void)
  37. {
  38.     int i;

  39.     void *data[N];

  40.     printf("The first time :\n");
  41.     for (i = 0; i < N; i++) {
  42.         data[i] = my_alloc(8);
  43.         printf("%p ", data[i]);
  44.     }

  45.     printf("\n\n");

  46.     
  47.     for (i = 0; i < N;i++) {
  48.         my_free(data[i]);
  49.         my_show();
  50.     }
  51.     
  52.     printf("The second time :\n");
  53.     for (i = 0; i < N; i++) {
  54.         data[i] = my_alloc(8);
  55.         printf("%p ", data[i]);
  56.     }
  57.     
  58.     printf("\n\n");

  59.     for (i = 0; i < N;i++) {
  60.         my_free(data[i]);
  61.         my_show();
  62.     }

  63.     return 0;

  64. }


不知大家是否注意到,这里从头到尾都没有链表,但是事实上仍是链表,只不过这里是通过指针的“跳跃”来实现链表互连的,即类似于用 ptr = *ptr 转向链表的下一个节点。另外,如果显式地用链表串联各空闲节点,对于每个空闲节点都要next指针,其实有点多余了。而这里next指针直接在空闲节点内存中存储了,反正这些内存都已经释放了,闲着也是闲着,还不如顺便保存一下next嘛,是吧。
阅读(4262) | 评论(5) | 转发(0) |
给主人留下些什么吧!~~

GFree_Wind2012-04-17 20:35:43

jmy2446267: 您好,这里void *data[N]只是为了便于测试而已,免得要测试free()时找不到之前alloc的内存。另外,我对alloc函数修改了一下,请您再看看.....
嗯。是我开始的时候想错了。
确实一个指针链表就够了。不需要多余的变量了。

jmy24462672012-04-17 18:39:27

GFree_Wind: 其实这样与链表没什么区别。对于你的这个例子,一个单链表的典型结构
struct mem_node {
    struct mem_node *next;
    void *data;
};

固然目前代码中使用f.....
您好,这里void *data[N]只是为了便于测试而已,免得要测试free()时找不到之前alloc的内存。另外,我对alloc函数修改了一下,请您再看看

重返人生2012-04-17 15:43:39

呵呵,不错的文章,比较好玩

十七岁的回忆2012-04-16 21:18:51

不错,提供了一种方法,实用性先不讲,还是可以了解一下的····

GFree_Wind2012-04-16 12:26:49

其实这样与链表没什么区别。对于你的这个例子,一个单链表的典型结构
struct mem_node {
    struct mem_node *next;
    void *data;
};

固然目前代码中使用free_list来取代链表,但是你代码中同样还需要void *data[N];来保存内存地址。内存一点也没省。

所以我觉得这种技巧还不如直接使用链表清晰明了呢。