Saturday, March 29, 2008

读书笔记之内存分配

Linux Programming by Example----内存分配


1. 作者说Never assume that memory allocation will succeed.因此,在每次分配之后,都要检查内存分配函数的返回值。如果是NULL,则分配失败。

2. 把一个指针free()两次,称作double free,其后果是ISO C undefined,亦即是说,其后果由implement决定。那么究竟会有什么危险?因为只要implement实现得比较周全,double free可以完全无害。

3. malloc(), calloc() & realloc().三个函数的关系如下:
malloc()分配指定大小的内存,calloc()不仅分配内存,还把内存清零。所以把malloc() wrap一下,即可实现calloc()。
realloc()原型是void* realloc(void* ptr, size_t newsize), 在ptr为NULL的时候,它可以实现malloc(),而在newsize为0的时候,它相当于free()。

4. realloc()函数有一个非常需要注意的特点,它可能移动整块ptr所指的内存,所以realloc之后,所有之前的指针都失效了,需要重新赋值。这一点,在ptr是数组头指针的时候,尤其重要。比如
char ptr[100];
char *second=ptr[1];
realloc(ptr,200);
之后,second失效。不能再用second存取第二个char了。

5. alloca()函数比较怪异,它不是在heap,而是在stack分配内存,因此它分配的内存无需程序员free(),调用函数退出后内存自然释放了。这个函数不是标准函数,ISO C或者POSIX都没有包含它。不提倡使用。不过我觉得这个函数看上去很handy。

6. 问题, malloc为什么叫malloc,calloc为什么叫calloc,realloc我倒是明白。

7. char* strdup(const char* str)这个函数非常怪异,它的实现调用malloc(),返回一个指向堆内存的指针。因此它返回的指针在使用完毕后,应该用free()释放。我坚决不会使用这个愚蠢的函数,尽管它是POSIX标准包含的。

8. gawk使用自己的内存allocator,用宏实现,部分代码如下:
#define getnode(n) if(nextfree) n=nextfree,nextfree=nextfree->nextp;\
else n=more_nodes
#define freenode(n) ((n)->flag=0, (n)->exec_count=0,\
(n)->nextp=nextfree,nextfree=(n))
这个allocator在需要大量同样规则的小内存块的情况下,效率较高。

Labels:

0 Comments:

Post a Comment

<< Home