13深入理解C指针之---内存管理

  该系列文章源于《深入理解C指针》的阅读与理解,由于本人的见识和知识的欠缺可能有误,还望大家批评指教。

  内存管理对所有程序都很重要,主要包括显式内存管理和隐式内存管理。其中隐式内存管理主要是自动变量分配内存,变量主要分配在函数的栈帧上。若是静态变量或全局变量,主要分配在程序的数据段,能够被自动分配数值。显式内存分配可以更加灵活高效的管理内存,可以有效避免空间浪费。C语言支持动态内存管理,对象从堆上分配内存,使用内存分配函数和内存释放函数实现内存的动态管理。

  一、内存分配流程:缺少任何环节都有可能出现问题

    1、使用内存分配函数分配内存主要包括malloc、calloc、realloc、alloca等

    2、使用分配的内存支持应用程序

    3、使用free函数释放内存,将内存空间返还给系统

  隐式内存管理代码如下:

 1 #include <stdio.h>
 2
 3 int main(int argc, char **argv)
 4 {
 5     int var1 = 5;
 6     int *ptrVar = &var1;
 7     printf("The var1 is %d and address is %p\n", var1, &var1);
 8     printf("The *ptrVar is %d and ptrVar is %p and ptrVar address is %p\n", *ptrVar, ptrVar, &ptrVar);
 9
10     return 0;
11 }

  显式内存管理代码如下:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3
 4 int main(int argc, char **argv)
 5 {
 6     int *var1 = (int *)malloc(sizeof(int));
 7     *var1 = 5;
 8     int *ptrVar = var1;
 9     printf("The *var1 is %d and var1 is %p and address is %p\n", *var1, var1, &var1);
10     printf("The *ptrVar is %d and ptrVar is %p and ptrVar address is %p\n", *ptrVar, ptrVar, &ptrVar);
11
12     return 0;
13 }

  指针使用完毕,记得释放内存,释放内存,释放内存,重要的事情说三遍,否则容易造成内存泄露。

  1)、分配内存时,需要自行把握内存空间的大小,否则可以越界访问数据,代码如下:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3
 4 int main(int argc, char **argv)
 5 {
 6     char *pc = (char*)malloc(sizeof(char) * 6);
 7     for(int i = 0; i < 18; i++){
 8         pc[i] = 97 + i;
 9     }
10     for(int i = 0; i < 18; i++){
11         printf("%c", pc[i]);
12     }
13     printf("\n");
14     free(pc);
15
16     return 0;
17 }

  上面代码,申请了6个字节的空间,但是可以使用18个字节的字符。

  2)、realloc函数的应用,需要自行把握空间的大小,代码如下:

 1 /* *=+=+=+=+* *** *=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
 2   * 作者代号: *** :guochaoxxl
 3   * 版权声明: *** :(魎魍魅魑)GPL3
 4   * 联络信箱: *** :guochaoxxl@gmail.com
 5   * 文档用途: *** :深入理解C指针
 6   * 文档信息: *** :~/WORKM/StudyCode/CodeStudy/cnblogs_understanding_and_using_c_pointers/chapter2/test12.c
 7   * 修订时间: *** :2017年第39周 10月01日 星期日 下午01:32 (274天)
 8   * 代码说明: *** :演示realloc函数的使用
 9  * *+=+=+=+=* *** *+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+*/
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 int main(int argc, char **argv)
15 {
16     char *arrCh1 = (char *)malloc(sizeof(char) * 8);
17     //arrCh1 = "teacherg";
18     strcpy(arrCh1, "teacherg");
19     printf("arrCh1: %p and value: %s\n", arrCh1, arrCh1);
20
21     char *arrCh2 = (char *)realloc(arrCh1, sizeof(char) * 256);
22     if(arrCh2)                                              //只要新的内存arrCh2分配成功,函数realloc会自动释放arrCh1
23     {
24         printf("Memory Reallocated at: %p\n",arrCh2);
25     }else{
26         printf("Not Enough Memory!/n");
27         free(arrCh1);                                       //若分配内存失败,则需要手动释放内存,否则内存泄露
28         arrCh1 = NULL;
29
30         return -1;
31     }
32     printf("arrCh1: %p and value: %s\n", arrCh1, arrCh1);   //只能获取arrCh1的地址,而无法获取内容
33     strcat(arrCh2, "uo good");                              //arrCh2中已包含原来arrCh1中内容,添加新内容
34     printf("arrCh2: %p and value: %s\n", arrCh2, arrCh2);   //获取arrCh2的地址和内容
35     free(arrCh2);                                           //释放内存
36
37     return 0;
38 }

  需要注意的是:第17行代码虽然和第18行代码的作用看似是一样的,但是在本例中,只能使用第18行,主要是使用字符串赋值是使用常量池,对后面分配内存的环节有影响,可以自行运行下代码,再思考下就会明白。

  至于calloc和alloc函数,比较简单,就不罗嗦了。

  

posted @ 2017-06-08 06:19  叕叒双又  阅读(396)  评论(0编辑  收藏  举报