【空间】C++内存管理
1、程序的大小布局
- 正文段(Text)用于存储指令,二进制代码,程序内容
- 数据段(Data)用于存储已初始化的全局变量
- BSS段(BSS)用于存储未赋值的全局变量所需的空间
2、程序的内存布局
在C++中,内存分成5个区,他们分别是
栈区(stack):由编译器自动分配释放,其操作方式类似于数据结构的栈(后进先出-LIFO)。在函数体中定义的局部变量通常是在栈上。
堆区(heap):就是那些由new/malloc/calloc/realloc分配,free释放分配的内存块。若程序员不释放的话,程序结束时由OS回收。
全局区(static):也叫静态数据内存空间,存储全局变量和静态变量,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。//C++中在所有函数体外定义的全局变量,加了static修饰符后的变量不管其在程序中的哪个位置,它都会被存放在全局区(静态区)
常量区(.text):常量字符串就是放在这里,程序结束后由系统释放。
代码区(.data):存放程序本身的二进制代码。
比如:
//例char* 和char[]的区别由此可见
int var = 0;//全局初始化区
char *p1; //全局未初始化区
void main(){
int b; //栈
int s[] = "abc"; //栈
char *p3 = "123456"; //123456在常量区,p3在栈上
char *p2; //栈
static int c = 0; //全局(静态)初始化区
p1 = (char)malloc(10); //分配得来得10字节的区域在堆区
p2 = (char)malloc(20); //分配得来得20字节的区域在堆区
strcpy(p1, "123456"); //"123456"放在常量区,编译器可能会将它与p3所向"123456"优化成一个
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
3、堆栈和内存分配
栈(Stack)
- 主要特点?
- 1)相比堆而言在栈上分配要快的多
- 2)在栈上的数据可以直接访问(不是非要使用指针访问)。
- 3)当你程序启动时决定栈的容量上限(可以用命令指定)。
- 4)当用栈过多时可导致栈溢出(无穷次(大量的)的递归调用,或者大量的内存分配)。
————————— - 何时需要?
- 1)较小内存的变量, 如1KB,10KB,100KB级别的内存
- 2)较短的生存时间,如函数中的局部变量
————————— - 如何分配?
- 1)函数中定义一个局部变量即可。
堆(Heap)
- 主要特点?
- 1)相比在栈上分配内存要慢。
- 2)在堆上的变量必须要手动分配和释放
- 3)如果申请的缓冲区过大的话,可能申请失败。
- 4)大量的分配和释放可造成内存碎片,甚至造成内存泄露
————————— - 何时需要?
- 1) 当需要分配一大块内存时,如一个很大的数组,一个很大的结构体,一个很大的类的实例。 一般当需要分配的内存达到几千个字节时,推荐在堆上分配,比如构建一个包含1000个整数的数组:
int *array = malloc(1000*sizeof(int));
- 2) 当希望变量的生存时间很长时(如全局可见)
- 3) 当希望变量能动态的改变大小时(如能动态增加大小的数组,链表或者预先不能估计大小)
————————— - 如何分配?
- 1)C语言分配(malloc):malloc只有一个参数,即需要分配的内存的字节数。malloc的返回值有两种:当分配成功时,malloc分配size大小的内存区块,返回指向这个内存块的首地址(指针)。返回的指针是void类型的,void将会被转化成希望的指针类型。当分配失败时,返回一个指向null的空指针,一般是内存区域不足时。//以及注意,malloc分配的内存是未被初始化的。
- 2)C语言释放(free):free函数的参数是指向一个内存区块的指针,free函数没有返回值。
3)C++分配:
int p_scalar = new int(5); //allocates an integer, set to 5. (same syntax as constructors)
int p_array = new int[5]; //allocates an array of 5 adjacent integers. (undefined values)
new若执行成功,它会做3件事:分配内存+调用构造函数初始化内存区域+返回内存区域的地址。new若执行失败,会抛出异常(an exception of type std::bad_alloc )4)C++释放:
delete p_var
- 5)C/C++区别:对于非内部数据类型的对象而言,对象在创建的同时要自动执行构造函数,对象在消亡之前要自动执行析构函数。由于malloc/free是库函数而不是运算符,不在编译器控制权限之内,不能够把执行构造函数和析构函数的任务强加于 malloc/free。因此C++语言需要一个能完成动态内存分配和初始化工作的运算符new,以及一个能完成清理与释放内存工作的运算符delete。
4、参考资料
内存管理C++
C++内存管理
char和char[]的区别
Anatomy of a Program in Memory
What a C programmer should know about memory
《程序员的自我修养——链接、装载与库》
《高质量 C++/C 编程指南》
The Descent to C
Guide to Advanced Programming in C
What and where are the stack and heap?
What’s the difference between a stack and a heap?
文章来源: gwj1314.blog.csdn.net,作者:小哈里,版权归原作者所有,如需转载,请联系作者。
原文链接:gwj1314.blog.csdn.net/article/details/80631443
- 点赞
- 收藏
- 关注作者
评论(0)