c++堆与栈的简单认识

Posted 不谇

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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读取字符,显然慢了。

     

     

以上是关于c++堆与栈的简单认识的主要内容,如果未能解决你的问题,请参考以下文章

简单总结:堆与栈的区别

让你彻底明白JAVA中堆与栈的区别

java中堆与栈的区别

堆与栈的比较

堆与栈的区别

Heap Spray:堆与栈的协同攻击