C语言中动态内存管理方式(malloc、calloc、realloc的区别)
文章目录
一、内存分布
说明:
- 栈又叫堆栈,非静态局部变量/函数参数/返回值等等,栈是向下增长的。
- 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。
- 堆用于程序运行时动态内存分配,堆是可以上增长的。
- 数据段,存储全局数据和静态数据。
- 代码段,可执行的代码/只读常量。
不同区域有着不同的功能,方便操作系统管理这些数据。比如房子有客厅、卧室、厨房、卫生间等等,各自有着不同功能。
二、什么是动态内存?
用户自己申请的内容空间并且用完之后需要动态进行释放的空间。
动态:用户申请 用户释放
三、为什么需要进行动态内存申请?
在内存不同的区域存放不同的数据,用户数据存储的位置是栈、堆。用户的数据可能非常大,栈区存储不下,需要更大内存空间存储数据,因此会向操作系统获取。
四、动态内存申请时注意的问题
1.用多少申请多少
2.使用时,不要越界
3.用完之后记得及时归还
五、C语言中是如何来进行内存申请的?
1.必须要包含对应的头文件
2.使用动态内存申请的函数:malloc/calloc/realloc
3.空间使用完成之后一定要归还:free
六、malloc/calloc/realloc的区别
相同点:
1.都是C语言标准的库函数
2.使用都必须包含对应的头文件
3.都是用来进行动态内存空间申请的
4.申请的空间都在堆上
5.申请空间成功返回空间的首地址,申请空间失败返回NULL,因此在使用前必须判空
6.它们的返回值类型都是void*,在使用时候必须要进行强制类型转换
7.用完之后一定要用free进行释放
不同点:
void* malloc(size_t size)
1.参数是所需要空间的字节数
2.返回值是void* 使用时必须要进行强制类型转换
3.申请空间成功返回空间的首地址,申请空间失败返回NULL,因此在使用前必须判空
4.用完之后一定要用free进行释放
void* calloc(size_t num,size_t size)
参数:num表示元素的个数,size表示单个元素的大小
calloc会对申请的空间使用0来进行初始化
void* realloc(void* ptr,size_t size)
主要功能:将ptr指向的空间大小调整到size字节,完成后返回空间的首地址。
1.如果ptr是空:功能与malloc类似,即直接申请size个字节返回
2.如果ptr非空:将ptr指向的空间大小调整到size字节,完成后返回空间的首地址。
假设:ptr指向空间的实际大小为oldsize个字节
1.size<oldsize:说明本次是需要将原空间缩小,realloc会直接在原空间基础上来进行调整,然后返回原空间的首地址。
2.size>oldsize:说明本次是需要将原空间扩大到size个字节。
->大一点:直接将ptr指向的空间原地扩大就可以了;
->大很多:ptr指向空间不能直接往后延,否则会覆盖其他数据
正确做法:
a.重新申请size个自己的新内存空间
b.将原来ptr指向的空间中内容拷贝到新空间
c.释放原来的ptr指向的空间
d.返回新申请的size个字节空间的首地址