zoukankan      html  css  js  c++  java
  • c++堆与栈的简单认识

    • 堆: 操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删 除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样代码 中的delete语句才能正确的释放本内存空间。我们常说的内存泄露,最常见的就是堆泄露(还有资源泄露),它是指程序在运行中出现泄露,如果程序被关闭掉的话,操作系统会帮助释放泄露的内存。

      栈:在函数调用时第一个进栈的主函数中的下一条指令(函数调用语句的下一条可执行语句)的地址然后是函数 的各个参数,在大多数的C编译器中,参数是由右往左入栈,然后是函数中的局部变量。(参考课本)

       1 #include <iostream>
       2  
       3  int main(void)
       4  {
       5      using namespace std;
       6      double * a = new double(5);
       7      int b = 1;
       8      cout << *a << endl;
       9      cout << a << endl;
      10      cout << &b << endl;
      11  
      12      delete a;
      13      return 0;
      14  }
      15  
      16  /***********************************
      17   * 5
      18   * 0x1002c20         ----->heap(堆)
      19   * 0x7ffe7bd82ec4    ----->stack(栈) 
      20   * *********************************/
      21  ~                                                     

       

      堆和栈地地址格式不一样。说明它们在内存中地位置不一样。


    • 一个由c/C++编译的程序占用的内存分为以下几个部分

      1、栈区(stack由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。

      2、堆区(heap一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。

      3、全局区(静态区)(static,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放

      4、文字常量区常量字符串就是放在这里的。 程序结束后由系统释放

      5、程序代码区存放函数体的二进制代码。(复制来自:http://www.cnblogs.com/likwo/archive/2010/12/20/1911026.html)

    • char a[] = "I like comouter!";       //I like conputer 时运行时分配的。意味着程序每次运行存储该字符串的地址都不一样。
      char *b = "I like computer!"               // I like conouter 是编译时就分配的。意味着一旦程序生成可执行代码,每次编译该字符串的地址都不再发生改变。

       1 #include <iostream>
       2  
       3  int main(void)
       4  {
       5      using namespace std;
       6  
       7      char a[] = "I like comouter!";
       8      char *b =  "I like conputer!";
       9  
      10      cout << (void *)a << endl;
      11      cout << (void *)b << endl;
      12  
      13      return 0;
      14  }
      15  
      16  /*************************************
      17   * [root@Busui cc]#c++ s./string
      18   * 0x7ffe4868c8e0
      19   * 0x400991
      20   * [root@Busui cc]#c++ s./string
      21   * 0x7ffdd6c640e0
      22   * 0x400991
      23   * [root@Busui cc]#./string
      24   * 0x7fffaffc7ce0
      25   * 0x400991
      26   * [root@Busui cc]#
      27   * ***********************************/

      以下是别人博客复制来的,博客地址上面已给出:

      2.6存取效率的比较

       

      char s1[] = "aaaaaaaaaaaaaaa";

      char *s2 = "bbbbbbbbbbbbbbbbb";

      aaaaaaaaaaa是在运行时刻赋值的;

      bbbbbbbbbbb是在编译时就确定的;

      但是,在以后的存取中,在栈上的数组比指针所指向的字符串(例如堆)快。

      比如:

      i nclude

      void main()

      {

      char a = 1;

      char c[] = "1234567890";

      char *p ="1234567890";

      a = c[1];

      a = p[1];

      return;

      }

      对应的汇编代码

      10: a = c[1];

      00401067 8A 4D F1 mov cl,byte ptr [ebp-0Fh]

      0040106A 88 4D FC mov byte ptr [ebp-4],cl

      11: a = p[1];

      0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]

      00401070 8A 42 01 mov al,byte ptr [edx+1]

      00401073 88 45 FC mov byte ptr [ebp-4],al

      第一种在读取时直接就把字符串中的元素读到寄存器cl中,而第二种则要先把指针值读到edx中,在根据edx读取字符,显然慢了。

       

  • 相关阅读:
    列表与数组 Perl入门第三章
    北京地区-医类汇总
    via/route blockage/size blockage/wire/pin guide/pin blockage/partition
    dbGet(三)
    dbGet(二.一)hinst
    微服务是什么?
    Docker入门 四 Swarms集群
    Docker入门 三 用服务来扩展和负载均衡你的应用
    Linux2.2路径、删除目录及文件
    Linux2.1系统目录结构、ls、文件类型、alias
  • 原文地址:https://www.cnblogs.com/busui/p/5814829.html
Copyright © 2011-2022 走看看