zoukankan      html  css  js  c++  java
  • 【空间】C++内存管理

    1、程序的大小布局
    • 正文段(Text)用于存储指令,二进制代码,程序内容
    • 数据段(Data)用于存储已初始化的全局变量
    • BSS段(BSS)用于存储未赋值的全局变量所需的空间
      DEC是总大小,HEX是16进制描述
    2、程序的内存布局

    在C++中,内存分成5个区,他们分别是

    • 栈区(stack):由编译器自动分配释放,其操作方式类似于数据结构的栈(后进先出-LIFO)。在函数体中定义的局部变量通常是在栈上。

    • 堆区(heap):就是那些由new/malloc/calloc/realloc分配,free释放分配的内存块。若程序员不释放的话,程序结束时由OS回收。

    • 全局区(static):也叫静态数据内存空间,存储全局变量和静态变量,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。//C++中在所有函数体外定义的全局变量,加了static修饰符后的变量不管其在程序中的哪个位置,它都会被存放在全局区(静态区)

    • 常量区(.text):常量字符串就是放在这里,程序结束后由系统释放。

    • 代码区(.data):存放程序本身的二进制代码。

    图解

    比如:

    //例char* 和char[]的区别由此可见
    int var = 0;//全局初始化区
    char *p1; //全局未初始化区
    void main(){
        int b;  //栈
        int s[] = "abc"; //栈
        char *p3 = "123456"; //123456在常量区,p3在栈上
        char *p2; //栈
        static int c = 0; //全局(静态)初始化区
        p1 = (char)malloc(10); //分配得来得10字节的区域在堆区
        p2 = (char)malloc(20); //分配得来得20字节的区域在堆区
        strcpy(p1, "123456"); //"123456"放在常量区,编译器可能会将它与p3所向"123456"优化成一个
    }
    3、堆栈和内存分配

    栈(Stack)

    • 主要特点?
    • 1)相比堆而言在栈上分配要快的多
    • 2)在栈上的数据可以直接访问(不是非要使用指针访问)。
    • 3)当你程序启动时决定栈的容量上限(可以用命令指定)。
    • 4)当用栈过多时可导致栈溢出(无穷次(大量的)的递归调用,或者大量的内存分配)。
      —————————
    • 何时需要?
    • 1)较小内存的变量, 如1KB,10KB,100KB级别的内存
    • 2)较短的生存时间,如函数中的局部变量
      —————————
    • 如何分配?
    • 1)函数中定义一个局部变量即可。

    堆(Heap)

    • 主要特点?
    • 1)相比在栈上分配内存要慢。
    • 2)在堆上的变量必须要手动分配和释放
    • 3)如果申请的缓冲区过大的话,可能申请失败。
    • 4)大量的分配和释放可造成内存碎片,甚至造成内存泄露
      —————————
    • 何时需要?
    • 1) 当需要分配一大块内存时,如一个很大的数组,一个很大的结构体,一个很大的类的实例。 一般当需要分配的内存达到几千个字节时,推荐在堆上分配,比如构建一个包含1000个整数的数组: int *array = malloc(1000*sizeof(int));
    • 2) 当希望变量的生存时间很长时(如全局可见)
    • 3) 当希望变量能动态的改变大小时(如能动态增加大小的数组,链表或者预先不能估计大小)
      —————————
    • 如何分配?
    • 1)C语言分配(malloc):malloc只有一个参数,即需要分配的内存的字节数。malloc的返回值有两种:当分配成功时,malloc分配size大小的内存区块,返回指向这个内存块的首地址(指针)。返回的指针是void类型的,void将会被转化成希望的指针类型。当分配失败时,返回一个指向null的空指针,一般是内存区域不足时。//以及注意,malloc分配的内存是未被初始化的。
    • 2)C语言释放(free):free函数的参数是指向一个内存区块的指针,free函数没有返回值。
    • 3)C++分配:
      int p_scalar = new int(5); //allocates an integer, set to 5. (same syntax as constructors)
      int p_array = new int[5]; //allocates an array of 5 adjacent integers. (undefined values)
      new若执行成功,它会做3件事:分配内存+调用构造函数初始化内存区域+返回内存区域的地址。new若执行失败,会抛出异常(an exception of type std::bad_alloc )

    • 4)C++释放:delete p_var

    • 5)C/C++区别:对于非内部数据类型的对象而言,对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于 malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。

    4、参考资料

    内存管理C++
    C++内存管理
    char和char[]的区别
    Anatomy of a Program in Memory
    What a C programmer should know about memory
    《程序员的自我修养——链接、装载与库》
    《高质量 C++/C 编程指南》
    The Descent to C
    Guide to Advanced Programming in C
    What and where are the stack and heap?
    What’s the difference between a stack and a heap?

  • 相关阅读:
    vue-fullcalendar插件
    iframe 父框架调用子框架的函数
    关于调试的一点感想
    hdfs 删除和新增节点
    hadoop yarn 实战错误汇总
    Ganglia 安装 No package 'ck' found
    storm on yarn(CDH5) 部署笔记
    spark on yarn 安装笔记
    storm on yarn安装时 提交到yarn失败 failed
    yarn storm spark
  • 原文地址:https://www.cnblogs.com/gwj1314/p/9444661.html
Copyright © 2011-2022 走看看