zoukankan      html  css  js  c++  java
  • 内存分段 && 缓冲区 && 析构函数

    一、内存中的程序:

     在进程被载入内存中时,基本上被分成许多小的节,以下是6个主要的节。

      低地址                                                   高地址

    .text 

      .text节基本上相当于二进制可执行文件的.text部分,它包含了完成程序任务的机器指令

      该节标记为只读,如果发生写操作,会造成 segmentation fault。

      在进程最初被加载到内存中开始,该节的大小就被固定。

    .data  

      .data节用来存储初始化过的变量

       如: int  a = 0;

      该节的大小在运行时是固定的。

    .bss  

      栈下节 (below stack section)用来存储未初始化的变量

      如: int  a;

      该节的大小在运行时是固定的。

    节(空闲存储器)

      堆节(heap section)用来存储动态分配的变量,位置从低地址向高地址增长。

      内存的分配和释放通过malloc()和free()函数控制。

      栈节(stack section)用来跟踪函数调用(可能是递归),在大多数系统上从内存的高地址向低地址增长。

    环境/参数

      环境/参数节(environment/ arguments section)用来存储系统环境变量的一份复制文件,进程在运行时可能需要。

      例如,运行中的进程可以通过环境变量来访问路径、shell名称、主机名等信息。该节是可写的。

      命令行参数也保存在该区域中。

    二、缓冲区

      缓冲区(buffer)是指这样一个存储区域:该区域用来接收和保存数据,直至进程对数据进行处理。由于各进程都有缓冲区,

    所以保持各进程缓冲区彼此无关是很重要的。通过在进程内存的 .data 和 .bss 节分配内存,可以做到这一点。

    三、析构函数

      如果类没有定义自己的析构函数,编译器会生成默认的析构函数。

    默认的析构函数不能删除在 堆(空闲存储器)上分配的对象和对象成员。

    因此,如果成员占用的空间是在构造函数中动态分配的,就必须自定义析构函数,然后释放以前分配的内存。

    使用C++智能指针,将自动删除空闲存储器中不再需要的内存。

     1 class CMessage
     2 {
     3 private:
     4     char * m_pMessage;
     5 
     6 public:
     7     void showIt()const
     8     {
     9         cout << m_pMessage << endl;
    10     }
    11 
    12     CMessage(const char* text="Default message")
    13     {
    14         size_t length{strlen(text)+1};
    15         m_pMessage = new char[length+1];
    16         strcpy_s(m_pMessage,length+1,text);
    17     }
    18 
    19     ~CMessage()
    20     {
    21         cout << "Destructor called" << endl;
    22         delete[]m_pMessage;
    23     }
    24 };
    25 
    26 int main()
    27 {
    28     CMessage motto{"Amiss is as good as a mile"};
    29     CMessage *pM{ new CMessage{"A cat can look at a queen"} };
    30 
    31     motto.showIt();
    32     pM->showIt();
    33 
    34     delete pM;
    35 
    36     return 0;
    37 }

    运行结果:

          Amiss is as good as a mile
          A cat can look at a queen
          Destructor called
          Destructor called

    现在注释掉: // delete pM;

    运行结果:

          Amiss is as good as a mile
          A cat can look at a queen
          Destructor called

    编译器为 motto 调用析构函数,是因为虽然该对象的数据成员占用的内存是由构造函数在堆上分配的,但它只是一个普通的自动对象。

    而 pM 在堆上为该对象分配内存,因此必须用 delete 删除此对象。

    当使用 delete 操作符删除动态创建的对象时,delete 操作符将在释放该对象占用的内存之前,首先调用该对象的析构函数。

  • 相关阅读:
    资料网站
    HTML、CSS部分
    面试题三
    面试题二
    面试题一
    上学时的HTML+JS+CSS(小总结)
    01.策略模式-上篇
    【解决方案】HTTP could not register URL http://+:6001/
    【问题与思考】1+"1"=?
    WCF安全3-Transport与Message安全模式
  • 原文地址:https://www.cnblogs.com/yunqie/p/5933785.html
Copyright © 2011-2022 走看看