一:动态内存分配
动态内存分配是C语言的强大功能
malloc单纯的从系统中申请固定大小的内存
calloc能以类型大小为单位申请内存并初始化0
realloc用于重置内存大小,参数point为NULL时,与malloc相同
free的参数为NULL时直接返回
void *malloc(size_t size)
void free(void *point)
void *calloc(size_t num,size_t size)
void *realloc(void *point,size_t size)
例如:
int* pI = (int*)malloc(5 * sizeof(int));
short* pS = (short*)calloc(5, sizeof(short));
pI = (int*)realloc(pI, 10);
二:栈,堆,静态区
栈:主要用于函数调用的使用(函数参数,函数返回地址,局部变量,函数调用上下文)
堆:内存的动态申请和归还
静态区:全局变量和静态变量,在编译器大小就已经确定
三:程序的内存布局
文件布局在内存中映射
堆栈段在程序运行后才正式存在,是程序运行的基础
.bss:未初始化的全局变量和静态变量
.text存放的是程序中可执行的代码
.data:已经初始化的全局变量和静态变量
.rodata:程序中的常量值,如字符串常量
静态存储区:.bss和.data
只读存储区:.rodata段
局部变量所占空间为栈上空间
动态空间为堆上空间
代码段:.test
四:野指针
野指针不是NULL指针,是指向不可用内存的指针
野指针来源:局部指针变量没有被初始化
使用已经释放过后的指针
指针所指向的变量在指针之前被销毁了
例如:如下,没有为指针指向一个合适的地址
struct Student
{
char* name;
int number;
};
struct Student s;
strcpy(s.name, "Delphi Tang");
解决办法:为name指针分配一个空间
函数入口校验
assert(NULL!=p)
为假终止运行,并提示出错,为真继续执行后面的代码
规则:
malloc申请内存后,应该立即检查指针为NULL
牢记数组长度,防止数组越界,必要时使用柔性数组
内存申请和释放相匹配
free指针后必须立即赋值为NULL,free(p);p=NULL;