堆栈区别

(1). 管理方式不同
(2). 空间大小不同
(3). 能否产生碎片
(4). 生长方向不同
(5). 分配效率不同

(1). 管理方式不同:
栈是由编译器自动申请释放内存,栈需要程序员手动管理,容易产生内存泄漏
(2). 空间大小不同:
栈的大小很小,只有1M,堆有2G,都可以适当扩大
(3). 能否产生碎片:
栈不会产生碎片,堆上申请的容易产生碎片
(4). 生长方向不同:
对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长。
(5). 分配效率不同:
栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,比较慢。

栈内存管理

程序栈中ebp,esp寄存器分别存放栈底,栈顶

#include<stdio.h>
int sum(int x,int y)
{
    int tmp = x+y;
    return tmp;
}
int mian()
{
    int x = 10;
    int y = 20;
    int ret = 0;
    ret = sum(y,x);
    return 0;
}

看懂kibana堆栈监控_函数栈

程序执行: #栈:高地址 ==> 低地址
1.开辟主函数栈,压入局部变量x.y.tmp
2.调用sum时从右向左传参,在调用函数栈上压入形参(esp减),压入下一条指令地址
3.将sum函数esp拉起(sum大小)并初始化为0XCCCCCCCC
4.进入sum函数栈中先压入调用方ebp,压入局部变量
5.返回值通过寄存器带出
6.mov esp ebp #栈帧回退,注:并没有清空,仍然存在
7.pop ebp     #回到原函数栈底
8.将下一条指令的地址送到CPU的PC寄存器
9.esp回退掉形参占用的位置

堆内存管理

堆内存是由提供的库函数管理:
malloc/new,free/delete区别:
1.malloc是C库函数,申请内存时需要添加字节数,返回类型是void* 所以需要强转为所需的指针类型,而new是C++的一个关键字,可以自动计算所需要的大小,并且返回所需类型的指针
2.malloc仅仅分配内存,而new在分配内存时调用构造函数
3.malloc不会抛出异常,new会抛出异常(构造函数的异常)
4.malloc分配的内存可以用realloc扩容,new的内存不可以扩容
5.malloc按大小分配,new按类型分配
6.当new一个数组时,需要用delete[ ] (内置类型不需要),因为new的数组头四字节存放的是数组长度。