C++ 内存分配

什么是内存

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

栈区(stack):由 编译器自动分配和释放,存放的是 运行时函数分配的局部变量,函数参数,返回数据,返回地址等参数,其操作类似于数据结构中的栈。

堆区(heap):一般 由程序员手动分配,如果程序员没有释放,程序结束时可能由os回收,其分配类似于链表。

全局区(静态区static):存放全局变量,静态数据,常量。程序结束后由系统释放,全局区分为已初始化全局区(data)和未初始化全局区(bss)。

常量区(文字常量区):存放常量字符串,程序结束后由系统释放

代码区:存放函数体(类成员函数和全局区)的二进制代码
.
.

三种内存分配方式:

一.从静态存储区分配内存
从静态存储区分配的内存在 程序编译的时候就已经被分配完毕了,这块内存在程序的整个运行期间都会存在(例如全局变量,static变量)

二.在栈上创建内存空间
在执行函数时, 函数内局部变量的存储单元可以在栈上创建,函数执行结束的时候,这些内存单元会自动被释放,栈内存分配运算内置于处理器的指令集,效率高,但是 分配的内存容量有限

三.在堆上分配内存(动态内存分配)????
在堆上分配内存亦被称为动态分配内存,程序在运行的时候使用malloc或者new申请 任意大小的内存,程序员自己负责在何时使用free和delete进行动态分配的内存的释放。 动态内存的生命周期是由程序员决定的,而且动态内存的申请和释放的使用过程非常灵活,but!如果在堆上分配了空间,则必须对堆上分配的内存进行回收,因为系统是无权对堆上的内存进行管理的,若只是申请了动态内存却不对内存进行释放,程序将会出现内存泄漏,且 频繁的分配和释放不同大小的堆空间将产生内存碎片。
.
.

内存分配的简易示意图:

C++ 内存分配
静态全局数据区:存放全局数据和静态数据
代码段:存放可执行代码和只读常量
堆区:存放动态开辟的变量
栈区:非静态局部变量、函数参数,返回值等

堆和栈的区别

管理方式不同:栈由编译器自动申请和释放空间,堆需要程序员手动申请和释放空间。

空间大小不同:栈的空间有限,32位平台下,VC6下默认为1M,而堆最大可以达到4G。

能否产生碎片: 栈和数据结构中的栈原理相同,在弹出一个元素之前,上一个元素已经弹出了,所以不会产生碎片,但如果不停的进行动态内存的申请和释放则会积累很多内存碎片。

生长方向的不同:堆的生长方向是向上的,也就是向着内存地址增加的方向,而栈刚好是相反的,栈是向着内存减小的方向生长的(因为栈的空间十分有限,所以栈是从上限往栈的下限生长的)

分配的方式不同:堆都是动态分配的,没有静态能进行分配的堆。而栈有静态分配和动态分配两种分配方式。静态分配是编译器完成的,比如局部变量的分配,动态分配在C++中由new函数进行分配。请注意:栈的动态分配和堆的是不同的,栈的动态分配由编译器进行释放,无需使用delete进行释放。

分配的效率不同:栈的效率比堆要高很多,因为栈是机器系统提供的数据结构,计算机在底层提供了栈的支持,分配专门的寄存器来存放栈的地址,压栈和出栈都有相应的指令,因此栈在分配的效率上是一定比堆上快的。而堆是由库函数提供的,机制很复杂,库函数会按照一定的算法进行搜索内存,因此比较慢。

静态全局变量(static),全局变量,静态局部变量(static),局部变量的区别:

静态全局变量和全局变量的区别:
1.静态全局变量和全局变量 都属于常量区
2.静态全局区 只在本文件中有效,别的文件如果向调用该变量,是调用不了的,且 全局变量在别的文件中还可以调用
3.如果别的文件中定义了一个该全局变量相同的的变量名,是会出错的。

静态局部变量和局部变量的区别:
1.静态局部变量是属于常量区的,而函数内部的局部变量属于栈区。
2.静态局部变量在该函数调用结束的时候,不会销毁,而是随着整个程序的结束而结束,静态局部变量不能被此函数外的函数调用。局部变量也是随着该函数的结束而结束的。
3.如果定义这两个变量的时候没有赋初始值,那么静态局部变量会自动的定义为0,而局部变量就是一个随机的值(一般的编译器会强制要求局部变量必须进行赋初值 而静态局部变量是否赋初值则不做强制性要求)。
4.静态局部变量在编译期间只赋值一次,以后每次调用函数时,不再赋值,而是直接调用上次的函数调用结束时的值。而局部变量在调用期间,每调用一次,便会对这个局部变量进行重新赋值

C++ 内存分配

总结:????
全局变量:可以被本程序所有对象或函数引用.
局部变量:只能被函数内部引用,而无法被其他的对象或函数引用.
全局静态变量:是在全局变量声明前加上一个static关键字,使该变量只能在这个源文件可用.
局部静态变量:通常放在函数内部,只能在函数内部被调用,只进行一次初始化,每次执行函数时保持上一次执行的值.

来自https://blog.csdn.net/cherrydreamsover/article/details/81627855
来自https://blog.csdn.net/cherrydreamsover/article/details/81627855
来自 C++动态内存管理项目