zoukankan      html  css  js  c++  java
  • 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
    ", var1, &var1);
     8     printf("The *ptrVar is %d and ptrVar is %p and ptrVar address is %p
    ", *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
    ", *var1, var1, &var1);
    10     printf("The *ptrVar is %d and ptrVar is %p and ptrVar address is %p
    ", *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("
    ");
    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
    ", 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
    ",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
    ", arrCh1, arrCh1);   //只能获取arrCh1的地址,而无法获取内容
    33     strcat(arrCh2, "uo good");                              //arrCh2中已包含原来arrCh1中内容,添加新内容
    34     printf("arrCh2: %p and value: %s
    ", arrCh2, arrCh2);   //获取arrCh2的地址和内容
    35     free(arrCh2);                                           //释放内存
    36
    37     return 0;
    38 }

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

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

      

  • 相关阅读:
    前端之CSS:属性操作2
    前端之CSS:属性操作1
    前端之CSS:CSS选择器
    前端之HTML:表单操作
    前端之HTML:HTML
    SQLAlchemy的使用(SQLAlchemy 是一种对象关系映射模型(Object Relational Mapper), 简称ORM。)
    IO多路复用
    协程
    线程的那些事儿
    并发编程的那些事儿(四)
  • 原文地址:https://www.cnblogs.com/guochaoxxl/p/6960830.html
Copyright © 2011-2022 走看看