关于C/C++内存分配

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

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

2、堆区(heap):是由程序员分配释放,若程序员不释放的话,程序结束时可能由OS回收,值得注意的是它与数据结构的堆是两回事,分配方式类似于数据结构的链表

3、全局区(static):也叫静态数据内存空间,存储全局变量和静态变量

data区:存放初始化的全局变量和静态变量。

BBS区:存放没有初始化的全局变量和静态变量,常量字符串存放在这里。程序结束后由系统释放。

4、程序代码区(code):存放函数体的二进制代码。

内存分配简易图

二、堆和栈的区别

 1)分配方式

栈:栈空间中申请,程序初始化时申请。

堆:程序员使用malloc或new自己申请空间。

2)申请后系统响应

栈:只要栈的剩余空间大于所申请的空间,系统将为程序提供内存,否则将报异常提示栈溢出。

堆:首先应该知道操作系统有一个记录内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请的空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序。

3)申请的效率不同

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

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

4)总结

数据量较小时,推荐使用栈空间申请,即直接定义数组。

数据量稍大或者不确定时,推荐使用堆空间内存,即使用malloc或者new动态申请,因为栈空间常常会有大小的限定,当栈空间耗尽时,栈溢出会导致程序崩溃。

三、Malloc和new

1)Malloc和free

malloc:申请指定字节数的内存。申请到的内存中的初始值不确定。需我们自己输入申请内存空间的字节数。

2)new 和delete

new / new[]:完成两件事,先底层调用 malloc 分配了内存,然后调用构造函数(创建对象)。申请内存时会自动计算所需字节数

delete/delete[]:也完成两件事,先调用析构函数(清理资源),然后底层调用 free 释放空间。

四、程序示例

可参照如下程序了解内存的分配方式

int a = 0; //全局初始化区
char *p1; //全局未初始化区
int main(){
    int b; //
    char s[] = "abc"; //
    char *p2; //
    char *p3 = "123456"; //123456在常量区,p3在栈上。
    static int c =0; //全局(静态)初始化区
    int arr[n];//存放在堆区
    p1 = (char *)malloc(10);
    p2 = (char *)malloc(20); //分配得来得10和20字节的区域就在堆区。
    strcpy(p1, "123456"); //123456放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
    return 0;
}

参考:https://blog.csdn.net/qq792326645/article/details/49783347 

参考:https://www.cnblogs.com/douzujun/p/10620802.html#_label0

原文地址:https://www.cnblogs.com/AntonioSu/p/12273116.html