第42课 - 内存操作经典问题分析二

第42课 - 内存操作经典问题分析二

1. 常见内存错误

(1)结构体成员指针未初始化

(2)结构体成员指针未分配足够的内存

(3)内存分配成功但并未初始化

(4)内存操作越界

【常见内存错误1】

 1 #include <stdio.h>
 2 #include <malloc.h>
 3 
 4 void test(int* p, int size) // 对内存操作时,有带长度信息
 5 {
 6     int i = 0;
 7     for(i = 0; i<size; i++)
 8     {
 9         printf("%d\n", p[i]);
10     }
11 
12     free(p);  // 不合符谁申请谁释放原则
13 }
14 
15 void func(unsigned int size)
16 {
17     int* p = (int*)malloc(size * sizeof(int));
18     int i = 0;
19 
20     if(size % 2 != 0)  // 当size为奇数时会产生内存泄漏
21     {
22          return;
23     }
24 
25     for(i=0; i<size; i++)
26     {
27         p[i] = i;
28         printf("%d\n", p[i]);
29     }
30 
31     free(p);
32 }
33 
34 int main()
35 {
36     int* p = (int*)malloc(5 * sizeof(int));
37     
38     test(p, 5);  // test内部释放了p所指内存,不符合谁申请谁释放原则
39 
40     free(p);     // 重复释放p  ==>  Error in `./a.out': double free or corruption (fasttop): 0x0000000001c29010 
41                  // 在main函数动态申请的内存应该在main函数中释放,谁申请谁释放
42 
43     func(9);     // 参数为奇数 ==> 产生内存泄漏
44     func(10);    // 正常
45 
46     return 0;
47 }

【常见内存错误2】

 1 #include <stdio.h>
 2 #include <malloc.h>
 3 
 4 struct Demo
 5 {
 6     char* p;
 7 };
 8 
 9 int main()
10 {
11     struct Demo d1;  // 结构体未被初始化,d1.a是野指针
12     struct Demo d2;
13 
14     char i = 0;
15     
16     for(i='a'; i< 'z'; i++)
17     {
18         d1.p[i] = i;  // d1.p是野指针,这里将产生段错误
19     }
20 
21     d2.p = (char*)calloc(5, sizeof(char));
22     
23     printf("%s\n", d2.p);
24 
25     for(i='a'; i< 'z'; i++)
26     {
27         d2.p[i] = i;  // 前面使用calloc只分配了5个字节,但是 'a'~'z'是26个字节,越界访问 
28     }
29 
30     free(d2.p);
31 
32     return 0;
33 }

2. 内存操作的交通规则

(1)动态内存申请之后,应该立即检查指针值是否为NULL,防止使用NULL指针

         

(2)free指针之后必须立即赋值为NULL

         

(3)任何与内存操作相关的函数都必须带长度信息  

         

(4)malloc操作和free操作必须匹配,遵循谁申请谁释放的原则,不要跨函数释放,防止内存泄漏和多次释放

  ● 当 malloc 的次数多于 free 时,会产生内存泄漏

  ● 当 malloc 的次数少于 free 时,程序可能崩溃

   

posted @ 2019-11-13 23:10  Hengs  阅读(325)  评论(0编辑  收藏  举报