关于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\0在常量区,p3在栈上。 static int c =0; //全局(静态)初始化区 int arr[n];//存放在堆区 p1 = (char *)malloc(10); p2 = (char *)malloc(20); //分配得来得10和20字节的区域就在堆区。 strcpy(p1, "123456"); //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。 return 0; }
参考:https://blog.csdn.net/qq792326645/article/details/49783347