堆内存管理
C语言中没有管理堆内存的语句,而是由标准库提供提供一套函数来管理堆内存。
头文件 #include <strings.h>
void *malloc(size_t size);
功能:向系统申请一块堆内存
size:内存块的字节数
返回值:
成功 返回内存块的首地址
失败 返回NULL
例:
char* node = malloc(sizeof(int));
//sizeof 计算字节数
使用malloc申请的内存,里面的内存是随机的、不确定的,如果需要对内存进行初始化可以使用以下函数:
头文件 #include <strings.h>
void bzero(void *s,size_t n);
功能:把一块内存的所有字节赋值为0
s:内存的首地址
n:内存块的字节数
头文件#include <string.h>
void *memset(void *s,int c,size_t n);
功能:把一块内存的所有字节赋值为c
s:内存的首地址
c:要赋值的数据,范围:0~255
n:内存块的字节数
当首次使用malloc申请内存时,malloc会向系统申请内存,而操作系统会一次分配33页内存给malloc管理,之后再使用malloc申请内存,就会从这33页内存中分配。
malloc分配的内存块之间有一些空隙,这些空隙中存在一个指针,这个指针所指向的空间记录malloc的管理信息,一旦破坏就会影响接下来malloc和free的使用。
void free(void *ptr);
功能:释放内存
注意:
1、free可以释放空指针
2、一块内存释放两次会出现错误
3、只释放使用权,不会清理释放的内存
操作系统对堆内存的管理决定了是否产生段错误,而malloc、free只是在管理堆内存的使用权限,如果越界访问,可能会影响malloc、free的后续使用,也可能产生脏数据
头文件 #include <stdlib.h>
void *calloc(size_t nmemb,size_t size);
功能:按块分配堆内存
nmemb:要申请的块数
size:每块的字节数
返回值:申请的内存块的首地址
例:
char* node = calloc(i,sizeof(int));
// 申请 i 块 字节数为 int类型字节数 的内存
1、该函数其实底层调用的是malloc分配的是一整块内存,nmemb、size参数只是让代码的可读性更强,nmemb、size实参交换位置不影响最后的结果。
2、calloc会把分配的内存进行初始化为0,因此速度比malloc要慢。
头文件#include <stdlib.h>
void *realloc(void *ptr,size_t size);
功能:调整已经申请到的内存块的大小,可以往大调也可以往小调。
ptr:申请到的内存块首地址
size:最终内存块字节数
返回值:调整后的内存块首地址,如果在原块的基础上无法调整,realloc会重新申请一块size个字节的内存,然后把原ptr的内容拷贝,再把ptr释放。