动态内存分配区域:堆(heap),很大接近可用内存,内存申请和销毁需要程序自行管理
1.malloc:申请内存函数,需要引用stdlib.h,具体参考帮助手册
2.calloc:申请内存函数,把每个元素初始化为0,具体参考帮助手册
3.realloc:扩大内存函数,具体参考帮助手册
4.free:释放内存,不释放则内存泄漏
泄露的内存什么情况还给系统:
1.程序(进程)退出
2.关机(重启)
局部变量:定义在函数内部的变量,包括形参,在栈(stack)中,作用域在函数内部有效
生存周期:进入函数创建,退出函数销毁
void:没有,可以修饰返回值或者形参列表
void*:通过指针,仅仅只标记地址,不包含类型信息
应用场景:
1.需要根据变量作为长度定义数组
2.函数结束后还需要继续使用的内存(例如返回局部数组的地址,链表)
3.长度较大的数组(大内存,超过1M的大小)
malloc的应用
应用场景1:
int main()
{
int n = 10;
//int arr[n]; //error,错误变量不能作为数组的长度,c99合法
int* p = (int *)malloc(n*sizeof(int));//创建成功后,p类似数组名
assert(p ! = NULL);//设置断点,如果没有内存不足,再没有可分配空间自动退出
if(p == NULL)
{
perror("出错了");
return 0;
}
for (int i = 0; i < n; i++)
p[i] = i;
for (int i = 0; i < n; i++)
printf("%d",p[i]);
return 0;
}
应用场景2 :
char* GetStr()//error
{
char str[] = "hello world";
return str;//返回局部变量的地址,这是错误的
}
int main()
{
char* p = GetStr();
printf("%s\n", p);//乱码
return 0;
}
代码执行如下:
正确如下:
char* GetStr()
{
int len = strlen("hello world");
//char* str = (char*)malloc(len * sizeof(char));//常见错误,还有空格
char* str = (char*)malloc((len+1) * sizeof(char));
assert(str != NULL);
strcpy(str,"hello world");
return str;
}
int main()
{
char* p = GetStr();
printf("%s\n",p);
free(p);
return 0;
}
应用场景3(需要大容量的内存):
int main()
{
//定义1000000长度的int 数组
//int arr[1000000];//不能定义这么大的数组
//int* arr = (int*)malloc(1000000 * sizeof(int));//可行
//char* arr = (char*)malloc(1024 *1024 *1024);//1G,可行
char* arr = (char*)malloc(1024 * 1024 * 1024 * 2);//20亿字节,2G失败
if (arr == NULL) {
perror("出错了");
assert(arr != NULL);
printf("好了\n");
getchar();
free(arr);
}
return 0;
}
经过层层测试,大概测试出内存有最多2G可分配
calloc的应用
calloc会把动态申请的内存每个单元初始化为0。
int main()
{
int n = 10;
int* arr = (int*)calloc(n, sizeof(int));
for (int i = 0; i < n; i++)
printf("%d ",arr[i]);//输出n个 0
free(arr);
return 0;
}
程序执行如下:
free崩溃的原因
1.越界
2.移到指针
3.重复释放或者是释放非动态内存
越界导致free崩溃
int main()
{
int n = 10;
int* arr = (int*)malloc(n);//应该写成int* arr = (int*)malloc(n*sizeof(int))
assert(arr != NULL);
for (int i = 0; i < n; i++)
arr[i] = i;
for (int i = 0; i < n; i++)
printf("%d", arr[i]);
printf("\n");
free(arr);
return 0;
}
移到指针导致free崩溃
int main()
{
int n = 10;
int* arr = (int*)malloc(n*sizeof(int);
assert(arr != NULL);
for (int i = 0; i < n; i++)
{ //arr[i] = i;
*arr = i;
arr++;
}
printf("\n");
free(arr);
return 0;
}
重复释放同一段内存导致free崩溃
int main()
{
int n = 10;
int* arr = (int*)malloc(n * sizeof(int));
assert(arr != NULL);
for (int i = 0; i < n; i++)
{
arr[i] = i;
}
printf("\n");
free(arr);
printf("%p\n", arr);//此时此刻arr是野指针
free(NULL);//可以
free(arr);//崩溃,重复释放
return 0;
}
上面三段代码都会报错