防止内存泄露的几个良好的编码习惯
来源:互联网 发布:seo博客资源 编辑:程序博客网 时间:2024/04/29 21:40
以将子函数设计成共别人使用的 API 的思想来考虑如何设计子函数
----------情景:主调函数需要调用子函数 f,函数f返回一段数据区
1、在主调函数中分配好内存,将地址传递给子函数f。这样做的好处是,内存的释放工作交给分配者,子函数不用管,保证子函数的模块独立性。
与之对应的不良编码习惯是,子函数分配内存,将这段内存的首地址返回给主调函数,这样做的坏处很明显,调用者很容易忘记释放这段内存,因为这段内存不是他分配的。
比如这个函数(见 man page):
const char *inet_ntop(int af, const void *src, char *dst, socklen_t size);调用者需要自己分配一段内存用于保存点分十进制形式的 IP 地址,然后将首地址传递给 *dst 。
2、在子函数中将这段数据区声明为 static
例如(见 man page):
struct hostent *gethostbyname(const char *name);struct hostent *gethostbyaddr(const void *addr, socklen_t len, int type);struct hostent *gethostent(void);这几个函数都会返回一个指向一个 struct hostent 的指针 struct hostent * ,这段数据区是在子函数里面声明的,如果是采用动态分配对内存,调用者很容易忘记释放,因为这段内存不是他分配的;但如果用一般的自动变量,函数返回之后这段内存为自动销毁,所以不可行。因此,设计者将它设计成 static ,这样如果多次调用同一子函数,使用的数据区始终只有一份,可以有效防止内存泄露。
3、声明一对函数,一个分配内存,另一个用来释放内存
例如(见 man page)
int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res);void freeaddrinfo(struct addrinfo *res);
getaddrinfo() 返回一个链表(res),这个链表在子函数 getaddrinfo() 中生成,用 freeaddrinfo() 来释放这个链表。
----------情景:主调函数需要调用子函数 f,函数f返回一段数据区,但是这段数据区的大小事先不能确定,比如,要设计一个 DBMS ,主调函数传递查询条件(如 SQL 语句)给子函数,子函数返回查询结果集,很明显,这个查询结果集的大小事先无法确定,采用上面的第一种方法似乎行不通。
笔者想到了一种方法,就是调用者事先分配一小段内存,将指向这段内存的指针的地址(注意是指针的地址,即二级指针)传递给子函数,如果这段内存太小,可以在子函数中 realloc ,然后将主调函数中的指针指向 realloc 之后的内存。
- 防止内存泄露的几个良好的编码习惯
- 良好的编程习惯避免内存泄露
- java良好的编码习惯
- 养成良好的编码习惯
- Java良好的编码习惯建议
- 良好的编程习惯
- 培养良好的习惯
- 养成良好的习惯
- 良好的编程习惯
- 良好的编程习惯
- 良好的程序设计习惯
- 养成良好的习惯
- 养成良好的习惯
- 良好的开发习惯
- 良好的编程习惯~!
- 养成良好的习惯
- 良好的编程习惯
- 成功者良好的习惯
- AVR的DS18B20 温度采集示例程序(原发于2007-11-20)
- 稀疏表达:向量、矩阵与张量(上)
- 不能说のsecret 7
- QT下QTableWidget使用方法小结
- KMP(转载来自Matrix67原创)
- 防止内存泄露的几个良好的编码习惯
- HDU 4363 Draw and paint (DP)
- Android 数据存储
- 优先级队列几个应用详解
- Android BroadcastReceiver
- ios监听app音量的变化
- hdu 1540 Tunnel Warfare
- 关于运行ARM开发板上SD变成只读文件解决方案
- uva-146 - ID Codes