c++堆与栈的简单认识

不谇 不谇     2022-08-01     205

关键词:

  • 堆: 操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删 除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样代码 中的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读取字符,显然慢了。

     

     

堆与栈的区别

数据类型   Java虚拟机中,数据类型可以分为两类:基本类型和引用类型。基本类型的变量保存原始值,即:他代表的值就是数值本身;而引用类型的变量保存引用值。“引用值”代表了某个对象的引用,而不是对象... 查看详情

heapspray:堆与栈的协同攻击

1:应用场景在针对浏览器的攻击中,常常会结合使用堆和栈协同利用漏洞。(1)当浏览器或其使用的ActiveX控件中存在溢出漏洞时,攻击者就可以生成一个特殊的HTML文件来触发这个漏洞。(2)不管是堆溢出还是栈溢出,漏洞触发... 查看详情

堆与栈

静态分配是指在编译阶段就能确定大小,由编译器进行分配,堆不可以进行静态分配,堆的申请都是在执行过程中进行的。堆和栈的大小都可以设置,栈一般只有几KB。堆在动态分配时,要申请连续的内存空间,释放后会产生碎... 查看详情

java中的堆与栈

 对于初学者来说,java成员方法中的参数传递的究竟是什么可能有些疑惑,如果理解java在创建变量堆和栈的使用,一切就能清楚明白了。 java中堆和栈都是用来存放数据的地方。 1、栈的特点是存取速度快,数据可共... 查看详情

stm32的堆与栈与编译信息查看

STM32的堆与栈与编译信息查看因为一个项目中使用malloc函数动态分配内存400多个字节,返回为0,分配失败。查找失败原因,为堆空间不足分配导致。查看堆和栈分别设置了2K,按正常情况看应能满足分配空间,原因可能因为栈分... 查看详情

堆与栈区别

...寄存器是不够的,因此这个需要就使用了内存2内存的堆与栈内存:栈,堆栈堆2.1栈的理解对于栈,特点是先进后出;先进的在底部,后放的在顶部;如桶里放的东西,先放进去的内容最后才能拿出... 查看详情

堆与栈区别(代码片段)

...寄存器是不够的,因此这个需要就使用了内存2内存的堆与栈内存:栈,堆栈堆2.1栈的理解对于栈,特点是先进后出;先进的在底部,后放的在顶部;如桶里放的东西,先放进去的内容最后才能拿出... 查看详情

什么是栈区?

...,在《const的思考》一文中,我给出了6种方法)明确区分堆与栈在bbs上,堆与栈的区分问题,似乎是一个永恒的话题,由此可见,初学者对此往往是混淆不清的,所以我决定拿他第一个开刀。首先,我们举一个例子:voidf()int*p=ne... 查看详情

object的堆与栈变量

参考:1、http://ios.jobbole.com/81900/2、https://stackoverflow.com/questions/79923/what-and-where-are-the-stack-and-heap3、https://vikashazrati.wordpress.com/2007/10/01/quicktip-java-basics-stack-and-heap/ 查看详情

堆与栈(未完)

1,堆:堆是共享的,用于储存对象,内存中最大的存储空间,在虚拟机启动的时候就启动起来了    在对象使用结束后,GC会自动回收内存    在堆满后,会溢出,程序就会崩溃    内存不连续,可能产生碎片,需... 查看详情

java堆与栈

栈是运行时的单位,而堆是存储的单元。栈解决程序的运行问题,即程序如何执行,或者说如何处理数据,堆解决的是数据存储的问题,即数据怎么放,放在哪儿。  在java中一个线程就会相应有一个线程栈与之对应,这... 查看详情

java堆与栈

Java的堆是一个位于随机访问存储器(RAM)的运行时数据区。通常使用new操作符在堆中创建对象,它们不需要程序代码来显式的释放。堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译... 查看详情

程序的段堆与栈

1.程序就是编译出来的镜像,处于执行状态的程序叫进程.一个程序可以执行多次,每次执行会产生一个进程.2.程序镜像里有分成很多个段: 段其实就是在程序镜像文件里从一个位置到另一个位置范围里存放某种数据,便于系统... 查看详情

“java”内存区域-“堆与栈”

  本文是我阅读周志明老师《深入理解Java虚拟机-JVM高级特性与最佳实战》章节2.2的学习笔记。更多内容,请参考原书。  Java虚拟机在执行Java程序时会将其所管理的内存划分为若干个不同的数据区域,这些区域有各自的用... 查看详情

bss段数据段代码段堆与栈

BSS段:BSS段(bsssegment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。    BSS是英文BlockStartedbySymbol的简称。BSS段属于静态内存分配。数据段:数据段(datasegment)通常是指用来存放程序中已初始化的全局变... 查看详情

虚拟内存布局内存的分工堆与栈

进程的虚拟内存空间分为两个部分。低2GB(或3GB_)由应用程序使用。高2GB(或1GB)由系统内核程序使用。系统内核的内存空间中包含驱动程序,系统内核可运行程序、用于内存管理的数据结构(页文件夹、页表等),用于进程管理... 查看详情

堆与栈

一、数据结构中的堆与栈  在数据结构中,堆与栈为两种常见数据结构,数据结构共分为三大类:表、树、图,堆为树类数据结构,栈为表类数据结构。堆:  堆是一种经过排序的树形数据结构。每一个结点都有一个值,像... 查看详情

定义类+类实例化+属性+构造函数+匿名类型var+堆与栈+gc回收机制+值类型与引用类型

为了让编程更加清晰,把程序中的功能进行模块化划分,每个模块提供特定的功能,而且每个模块都是孤立的,这种模块化编程提供了非常大的多样性,大大增加了重用代码的机会。面向对象编程也叫做OOP编程简单来说面向对象... 查看详情