作者:hyuan 日期:2010-8-9 7:25:00
malloc函数具体实现:
以下是在linux2.6.14源码中找到的malloc函数实现
linux-2.6.14/arch/i386/boot/compressed/misc.c
源文件:http://lxr.linux.no/linux+v2.6.14/arch/i386/boot/compressed/misc.c
33 static void* memset(void *, int, size_t);
34 static void* memcpy(void *, __const void *, size_t);
35 #define memzero(s, n) memset ((s), 0, (n)) //定义外部调用接口
81 static void error(char *m);
82 static void gzip_mark(void **);
83 static void gzip_release(void **);
103 static void *malloc(int size);
//static限定malloc函数只能在本文件中使用。返回值是void *的指针,说明这里只管分配存储空间,不管空间具体用来存放哪种类型。size表示要申请的字节数。具体使用时例如我们int *p=(int*)malloc(sizeof(int));对其进行了显示强制类型转换。
104 static void free(void *where);
109 static long free_mem_ptr = (long)&end; //当前可分配内存的起始地址
110 static long free_mem_end_ptr; //内存区结束地址
//函数具体定义
130 static void *malloc(int size)
131 {
132 void *p;
133
134 if (size <0) error("Malloc error"); //注意:考虑size==0时,怎么分配
135 if (free_mem_ptr <= 0) error("Memory error");
136
137 free_mem_ptr = (free_mem_ptr + 3) & ~3; /* Align */ /*难点!!这里考虑到对齐的处理*/
138
139 p = (void *)free_mem_ptr; //free_mem_ptr为分配的内存区域的初始地址
140 free_mem_ptr += size; //保证分配足够的大小
141
142 if (free_mem_ptr >= free_mem_end_ptr)
143 error("Out of memory");
144
145 return p; //返回void型指针,表示只分配,不管具体用在哪种类型。
146 }
147
148 static void free(void *where)
149 { /* Don't care */ //为什么不定义呢?暂时还没搞懂
150 }
151
152 static void gzip_mark(void **ptr)
153 {
154 *ptr = (void *) free_mem_ptr;
155 }
156
157 static void gzip_release(void **ptr)
158 {
159 free_mem_ptr = (long) *ptr;
160 }
161
208 static void* memset(void* s, int c, size_t n)
209 {
210 int i;
211 char *ss = (char*)s;
212
213 for (i=0;i 214 return s;
215 }
216
217 static void* memcpy(void* __dest, __const void* __src,
218 size_t __n)
219 {
220 int i;
221 char *d = (char *)__dest, *s = (char *)__src;
222
223 for (i=0;i<__n;i++) d[i] = s[i];
224 return __dest;
225 }
//错误处理函数
287 static void error(char *x)
288 {
289 putstr("/n/n");
290 putstr(x);
291 putstr("/n/n -- System halted");
292
293 while(1); /* Halt */
294 }
http://lxr.linux.no/linux+v2.6.14/drivers/char/drm/tdfx_drv.h#L35
35 #define DRM(x) tdfx_##x
http://lxr.linux.no/linux+v2.6.14/drivers/char/drm/drm_memory_debug.h#L148
//内存分配函数
148 void *DRM(alloc)(size_t size, int area);
170 void *DRM(calloc)(size_t nmemb, size_t size, int area)
171 {
172 void *addr;
173
174 addr = DRM(alloc)(nmemb * size, area);
175 if (addr != NULL)
176 memset((void *)addr, 0, size * nmemb);
177
178 return addr;
179 }
181 void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area);
193 void DRM(free)(void *pt, size_t size, int area);
EXEMPLE1
//测试free函数
#i nclude
#i nclude
int main(void)
{
int *p;
printf("%d,%p/n",*p,p);
p=(int *)malloc(sizeof(int));
*p=123;
printf("%d,%p/n",*p,p);
free(p);
printf("%d,%p/n",*p,p);
return 0;
}
GCC编译运行后,输出如下:
1474660693,0xb7f75870
123,0x9f26008
0,0x9f26008
为什么是0呢?
EXEMPLE2:
释放内存不是丢掉指针。否则的话后患无穷。那么malloc到底做什么?free到底做什么?
简单的说,malloc在一个特定的内存区划出一块你利用参数指定的大小的内存块,然后把这块内存的开始地址返回。这要求你用一个指针来接收。否则也会出现内存泄漏。因为这块内存你申请了之后,并没有释放。说到这里补充一句,malloc函数分配的内存空间不会自动释放,需要你操作来完成。需要的操作就是free。那么free做什么呢?就是将指针指定的内存空间释放,如果发现指定的内存空间不是在与malloc匹配的内存空间,free操作就会失败。所以free做的是释放指针指向的用malloc申请的特定的内存空间,而不是指针本身。根据这个解释,下面的例子造成了内存泄漏:
h->next=(node*)malloc(sizeof(node));
h->next=NULL;//
如果这样做的话,申请的空间失去了指针的指定,就不可能得到释放。以后如果想要再次使用,也是不可能了。那么当你现在指向一块这样的内存空间的指针需要临时改变指向时该怎么办?很简单,先用别的指针临时指向。