zoukankan      html  css  js  c++  java
  • C++内存,堆区和栈区,函数调用栈,缓冲区溢出

    转载:堆和栈的区别

    https://blog.csdn.net/zhou13454069844/article/details/17549727
    https://blog.csdn.net/mynote/article/details/5835615
    https://blog.csdn.net/yingms/article/details/53188974

    栈空间由系统分配,尽量避免在栈上定义大数组、大对象,容易栈溢出导致程序崩溃

    使用new动态分配内存,是在上创建的,堆的空间足够大。

    一、程序的内存分配

    1.堆区

    存放程序动态分配的内存(new,malloc等函数分配的)

    2.栈区

    函数调用时的返回地址,参数压栈,局部变量,返回数据等都存放在栈区;栈内存是由系统自己分配和释放的,而堆内存要由程序员自己全全控制的,否则会出现内存泄露.

    3.全局数据区(有的地方将此划分为常量区和全局区(静态区))

    存放全局数据和静态数据以及常量;

    4.代码区

    顾名思义就是存放运行的代码的

    5.上面四个(或五个)内存区域的区别

    转载:写入到缓冲区溢出

    分配和管理方式不同

    • 堆是动态分配的,其空间的分配和释放都由程序员控制。也就是说,堆的大小并不固定,可动态扩张或缩减,其分配由 malloc() 等这类实时内存分配函数来实现。当进程调用 malloc 等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用 free 等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)。

    • 栈由编译器自动管理,其分配方式有两种:静态分配和动态分配。静态分配由编译器完成,比如局部变量的分配。动态分配由 alloca() 函数进行分配,但是栈的动态分配和堆是不同的,它的动态分配是由编译器进行释放,无需手工控制。

    申请的大小限制不同

    • 栈是向低地址扩展的数据结构,是一块连续的内存区域,栈顶的地址和栈的最大容量是系统预先规定好的,能从栈获得的空间较小。

    • 堆是向高地址扩展的数据结构,是不连续的内存区域,这是由于系统是由链表在存储空闲内存地址,自然堆就是不连续的内存区域,且链表的遍历也是从低地址向高地址遍历的,堆的大小受限于计算机系统的有效虚拟内存空间, 由此空间,堆获得的空间比较灵活,也比较大。在 32 位平台下,VC6 下默认为 1M,堆最大可以到 4G;

    申请效率不同

    • 栈由系统自动分配,速度快,但是程序员无法控制。

    • 堆是有程序员自己分配,速度较慢,容易产生碎片,不过用起来方便。

    产生碎片不同

    • 对堆来说,频繁执行malloc或free势必会造成内存空间的不连续,形成大量的碎片,使程序效率降低;

    • 对栈而言,则不存在碎片问题。

    内存地址增长的方向不同

    • 堆是向着内存地址增加的方向增长的,从内存的低地址向高地址方向增长;

    • 栈的增长方向与之相反,是向着内存地址减小的方向增长,由内存的高地址向低地址方向增长。

    二、数据结构中的堆和栈

    三、函数栈(调用栈)

    转载:函数调用--函数栈

    转载:函数调用栈

    四、缓冲区溢出

    缓冲区溢出主要分为四个方面

    栈溢出

    堆溢出

    BSS溢出

    格式化串溢出

  • 相关阅读:
    Golang 学习入坑(三)Go语言变量及常量及运算符
    Golang 学习入坑(二)Go语言结构及基本语法及基本类型
    docker 理解和一些应用
    golang学习入坑(一)Go介绍及环境搭建
    VMware安装Centos7超详细程
    2020-05-28 postgresql sequence
    2020-05-18 缓存穿透、缓存击穿、缓存雪崩
    2020-05-15 rocketmq-spring-starter支持多集群
    2020-05-15 rocketmq-spring-starter结合disconf使用
    2020-05-14 RSA加解密
  • 原文地址:https://www.cnblogs.com/mmmmmmmmm/p/14008189.html
Copyright © 2011-2022 走看看