一.为什么要有动态内存的分配
我们已经掌握的开辟空间的方法有:
但是上述开辟的空间有两个特点:
空间开辟的大小是固定的,数组在申明时必须指定数组的长度,数组空间一旦确定大小不能调整。但是我们对于空间的需求不仅仅是上面这种情况,有时我们需要的空间大小在程序运行时才能知道,那数组的编译时开辟空间的方式就不能满足了。
C语言引入动态内存开辟,让程序员自己可以申请释放空间,就比较灵活了。
二.malloc和free
这个函数向内存申请一块连续可用的空间,并返回这块空间的指针。
如果开辟成功,则返回一个开辟好空间的指针。
如果开辟失败,则返回一个null指针。
返回值为void*,使用者可以决定使用类型。
2.2free
free函数是用来专门做动态内存的释放和回收的
如果参数ptr指向的空间不是动态开辟,那free函数的行为是未定义的。
如果参数ptr是null指针,则函数什么事都不做。
malloc和free都在stdlib.h头文件中。
三.calloc和realloc
3.1calloc
C语言提供提供的一个calloc函数,原型如下
函数功能是为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0。与malloc的区别在于calloc会在返回地址前把申请空间的每个字节初始化为0。
所以如果我们对申请空间内容有初始化要求,可以用calloc完成。
3.2realloc
realloc函数的出现让动态内存管理更加灵活。
有时我们会发现过去申请空间太小或者太大,我们可以用realloc对函数空间进行调整
ptr是要调整的内存地址,size是调整之后的大小,返回值为调整之后的内存起始位置。
这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间。
realloc在调整内存空间有两种情况:
情况1:内存有足够空间
情况2:原有空间之后没有足够大的空间
情况1:当是情况1时,要扩展的内存直接在原有内存之后追加空间,原有空间的数据不变化。
情况2:原有空间没有足够多的空间时,会在堆空间上找另外一个合适大小的连续空间。这样函数返回的是一个新的地址。
三.柔性数组
在c99中,结构中的最后一个元素允许是未知大小的数组,这就叫做柔性数组。例如:
3.1柔性数组的特点
结构中柔性数组成员前面必须至少有一个其他成员,sizeof返回的这种结构大小不包括柔性数组的内存。包含柔性数组成员结构用malloc()函数进行动态分配,并且分配的内存应该大于结构大小,以适应柔性数组的预期。
四.c和c++中的内存区域划分
1.栈区:在执行函数时,函数局部变量的储存单位都可以在占上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率高,但是分配的内存容量有限。栈区主要存放运行函数而分配的局部变量,函数参数,返回数据,返回地址等。
2.堆区:一般由程序员分配释放,若程序员不释放,程序结束由OS回收,分配方式类似于链表。
3.数据段(静态区):存放全局变量,静态数据。程序结束后由系统释放。
4.代码段:存放函数体的二进制代码。