Chinaunix首页 | 论坛 | 博客
  • 博客访问: 329523
  • 博文数量: 57
  • 博客积分: 146
  • 博客等级: 入伍新兵
  • 技术积分: 769
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-29 14:57
文章分类
文章存档

2014年(39)

2013年(13)

2012年(5)

我的朋友

分类: C/C++

2014-07-15 10:44:46

一.内存资源被free后,不要对其进行读写操作。
当内存被释放,其内容可能会保持不变和可访问。若访问其内容可能发生意想不到的变化,导致意想不到的程序行为。因此,有必要保证内存一旦释放,就不能写入或读取。


错误代码:

点击(此处)折叠或打开

  1. for(p = head; p != NULL; p = p->next) {
  2.     free(p);
  3. }
在执行p=p->next前,p已经被free。

正确代码:

点击(此处)折叠或打开

  1. for (p = head; p != NULL; p = q) {
  2.     q = p->next;
  3.     free(p);
  4. }

二,只释放同一内存资源一次,避免double-free的问题。

错误代码:

点击(此处)折叠或打开

  1. x = malloc (number * sizeof(int));
  2. if (x == NULL) {
  3.     /* Handle Allocation Error */
  4. }
  5.     /* ... */
  6. if (error_conditon == 1) {
  7.     /* Handle Error Condition*/
  8.     free(x);
  9. }
  10. /* ... */
  11. free(x)

正确代码:

点击(此处)折叠或打开

  1. if (sizeof(int) > SIZE_MAX/number) {
  2.     /* handle overflow */
  3. }
  4. x = malloc(number * sizeof(int));
  5. if (x == NULL) {
  6.     /* Handle Allocation Error */
  7. }
  8. /* ... */
  9. if (error_conditon == 1) {
  10.     /* Handle Error Condition*/
  11. }
  12. /* ... */
  13. free(x)

三.有必要检查内存管理函数返回的状态并适当地处理错误



错误代码:

点击(此处)折叠或打开

  1. /* ... */
  2. p = realloc(p, new_size);
  3. if (p == NULL) {
  4.     /* Handle Error */
  5. }
  6. /* ... */
若realloc函数失败,p指针指向NULL,原始的内存区域则会没有释放而造成内存泄漏。

正确代码:

点击(此处)折叠或打开

  1. /* ... */
  2. q = realloc(p, new_size);
  3. if (q == NULL) {
  4. /* Handle Error */
  5. }
  6. p = q;
  7. /* ... */

四.free函数只能释放动态分配的内存资源
若free的内存不是动态配分的,会导致程序异常中断或其他错误(依赖于编译器)。

错误代码:

点击(此处)折叠或打开

  1. #define MAX_ALLOCATION 1000
  2. int main(int argc, char *argv[]) {
  3.     char *str = NULL;
  4.     size_t len;
  5.     if (argc == 2) {
  6.         len = strlen(argv[1])+1;
  7.         if (len > MAX_ALLOCATION) {
  8.             /* Handle Error */
  9.         }
  10.     str = malloc(len);
  11.     if (str == NULL) {
  12.         /* Handle Allocation Error */
  13.     }
  14.     strcpy(str, argv[1]);
  15.     }
  16.     else {
  17.     str = "usage: $>a.exe [string]";
  18.     printf("%s\n", str);
  19. }
  20. /* ... */
  21. free(str);
  22. return 0;
  23. }
若代码执行到17行后,str指向字符串常量,这里是str是不允许被free来释放的,会产生错误。

正确代码:

点击(此处)折叠或打开

  1. #define MAX_ALLOCATION 1000
  2. int main(int argc, char *argv[]) {
  3. char *str = NULL;
  4. size_t len;
  5. if (argc == 2) {
  6. len = strlen(argv[1])+1;
  7. if (len > MAX_ALLOCATION) {
  8. /* Handle Error */
  9. }
  10. str = malloc(len);
  11. if (str == NULL) {
  12. /* Handle Allocation Error */
  13. }
  14. strcpy(str, argv[1]);
  15. }
  16. else {
  17. printf("%s\n", "usage: $>a.exe [string]");
  18. return -1;
  19. }
  20. /* ... */
  21. free(str);
  22. return 0;
  23. }

五.为对象申请足够大的内存
malloc、calloc、realloc函数的size参数必须是有晓且能够容纳对象。若size大小不对或被恶意修改,会导致缓冲溢出。不正确的尺寸参数,检查范围不足,整数溢出,或截断可能导致缓冲区分配的大小不足。

错误代码:

点击(此处)折叠或打开

  1. void function(size_t len) {
  2. long *p;
  3. if (len > SIZE_MAX / sizeof(long)) {
  4. /* handle overflow */
  5. }
  6. p = malloc(len * sizeof(int));
  7. if (p == NULL) {
  8. /* handle error */
  9. }
  10. /* ... */
  11. free(p);
  12. }
若sizeof(long)大于sizeof(int), malloc(len*sizeof(int))分配的内存资源就会不够大。


正确代码:

点击(此处)折叠或打开

  1. void function(size_t len) {
  2. long *p;
  3. if (len > SIZE_MAX / sizeof(long)) {
  4. /* handle overflow */
  5. }
  6. p = malloc(len * sizeof(long));
  7. if (p == NULL) {
  8. /* handle error */
  9. }
  10. /* ... */
  11. free(p);
  12. }


阅读(1086) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~