[day05]二级指针分配内存,释放内存、防止野指针的手段、结构体操作(中嵌一二级指针,分配内存,释放内存)

1.二级指针分配内存,释放内存

主要围绕二级指针的第三种内存模型(自己构造内存)

 1 #include <stdio.h>
 2 
 3 #define PAR_CNT 10
 4 #define CHI_CNT 2
 5 
 6 /*创建10个二级指针,每个二级指针挂2个一级指针*/
 7 char ** create_mem()
 8 {
 9     char **pParent = NULL;
10     int i;
11 
12     pParent = (char **)malloc(PAR_CNT * sizeof(char *));
13     if (pParent == NULL) {
14         printf("func malloc() err \n");
15         return pParent;
16     }
17 
18     for (i=0; i<CHI_CNT; i++) {
19         pParent[i] = (char *)malloc(CHI_CNT * sizeof(char));
20         if (pParent[i] == NULL) {
21             printf("func malloc for pParent[%d] is err \n", i);
22             return NULL;
23         }
24     }
25     return pParent;
26 }
27 
28 int free_mem(char ** pArray)
29 {
30     /*先释放一级指针,也就是孩子指针内存*/
31     int i;
32     int ret = 0;
33 
34     if (pArray == NULL) {
35         ret = -1;
36         printf("不需要释放!\n");
37         return ret;
38     }
39 
40     for (i=0; i<CHI_CNT; i++) {
41         if (pArray[i] == NULL) {
42             ret = -1;
43             printf("不需要释放!\n");
44             return ret;
45         }
46 
47         free(pArray[i]);
48         //pArray[i] = NULL; /*这是一条垃圾语句*/
49 
50     }
51 
52     /*释放二级指针指向的内存块*/
53     free(pArray);
54     //pArray = NULL; /*同样这也是一条垃圾语句*/
55 
56     return ret;
57 }
58 
59 int main(void)
60 {
61     char **pArray = NULL;
62     int ret = 0;
63 
64     pArray = create_mem();
65     ret = free_mem(pArray);
66 
67     return 0;
68 }

注意:实参和形参是两个不同的东西,在释放的函数中释放之后置NULL是没有意义的。

 

2.防止野指针的手段

 防止野指针的手段

  1. 定义指针变量时置NULL。如:char *p = NULL;
  2. 释放之前判断是否为NULL。如:if (p != NULL) free(p);
  3. 释放之后置NULL。free(p); p=NULL;

 

3.结构体操作

结构体中嵌入一级,二级指针,分配内存,被调函数使用二级指针置NULL。

  1 #include <stdio.h>
  2 
  3 #define TCH_CNT 3 // 3名老师
  4 #define STU_CNT 2 // 每名老师2学生
  5 #define NAM_LEN 20
  6 
  7 typedef struct _Teacher
  8 {
  9     char name[NAM_LEN]; //20+4+4+4=32
 10     int age;
 11     char *a_name; //别名
 12     char **s_name; // 学生的名字
 13 }Teacher;
 14 
 15 //这里使用二级指针参数来把分配的内存传出来好了
 16 int create_mem(Teacher **t)
 17 {
 18     int ret = 0;
 19     int i, j;
 20 
 21     *t = (Teacher *)malloc(TCH_CNT * sizeof(Teacher));
 22 
 23     if (*t == NULL) {
 24         ret = -1;
 25         printf("func malloc() err: %d\n", ret);
 26         return ret;
 27     }
 28 
 29     //给这三名老师的名字和年龄赋值
 30     for (i=0; i<TCH_CNT; i++) {
 31         sprintf((*t+i)->name, "老师%d", i+1);
 32         (*t+i)->age = (i+1)*10;
 33 
 34         //给一级指针的别名分配内存
 35         (*t+i)->a_name = (char *)malloc(NAM_LEN * sizeof(char));
 36         //别名赋值
 37         sprintf((*t+i)->a_name, "%d老师", i+1);
 38 
 39         //给二级指针的老师的学生分配内存
 40         (*t+i)->s_name = (char **)malloc(STU_CNT * sizeof(char *));
 41         for (j=0; j<STU_CNT; j++) {
 42             (*t+i)->s_name[j] = (char *)malloc(NAM_LEN * sizeof(char));
 43             //给每个老师的每位学生赋值
 44             sprintf((*t+i)->s_name[j], "第%d位老师的第%d位学生", i+1, j+1);
 45         }
 46     }
 47 
 48     return ret;
 49 }
 50 
 51 void print_str(Teacher *t)
 52 {
 53     int i, j;
 54 
 55     for (i=0; i<TCH_CNT; i++) {
 56         printf("%s ", (t+i)->name);
 57         printf("%d ", t[i].age);
 58         printf("%s ", (t+i)->a_name);
 59         for (j=0; j<STU_CNT; j++) {
 60             printf("%s ", (t+i)->s_name[j]);
 61         }
 62         printf("\n");
 63     }
 64 }
 65 
 66 //这里使用二级指针刚好释放了直接置为NULL
 67 void free_mem(Teacher **t)
 68 {
 69     int i, j;
 70 
 71     if (*t != NULL)
 72     {
 73         for(i=0; i<TCH_CNT; i++) {
 74             //释放二级指针的学生姓名的空间
 75             for (j=0; j<STU_CNT; j++) {
 76                 if ((*t+i)->s_name != NULL) {
 77                     if ((*t+i)->s_name[j] != NULL) {
 78                         free((*t+i)->s_name[j]);
 79                         (*t+i)->s_name[j] = NULL;
 80                     }
 81 
 82                     free((*t+i)->s_name);
 83                     (*t+i)->s_name = NULL;
 84                 }
 85             }
 86 
 87             //释放一级指针的别名的空间
 88             if ((*t+i)->a_name != NULL) {
 89                 free((*t+i)->a_name);
 90                 (*t+i)->a_name = NULL;
 91             }
 92         }
 93 
 94         printf("t不为NULL,我要释放!\n");
 95         free(*t);
 96         *t = NULL;
 97     }
 98 }
 99 
100 int main(void)
101 {
102     Teacher *pt = NULL;
103 
104     //printf("%d\n", sizeof(t));
105     create_mem(&pt);
106 
107     //printf("%d\n", sizeof(*pt));
108     print_str(pt);
109 
110     free_mem(&pt);
111     printf("&pt=%d\n", pt); // pt的值已经置NULL了
112     //free_mem(&pt); // 因为使用二级指针,这里就算是调用释放多次,里面也不会执行了
113     return 0;
114 }

要想不适用返回值返回,如果主调函数是一级指针,那么参数请使用二级指针。分配内存的顺序和释放内存的顺序相反,此代码可能还不完善。

posted @ 2015-01-02 23:33  IFPELSET  阅读(1574)  评论(0)    收藏  举报