动态内存:可以解决(应用场景):
1、需要通过变量作为数组的长度int arr[n]
2、需要较大的内存
3、返回局部数组 局部变量:生命周期短(进入函数创建,函数结束销毁)
三种代码应用:(都需要引用stdlib.h文件)
1、malloc(是无类型的void*,需要强转):分配的内存为随机值
void* 无类型的地址,通用地址,泛指地址
char* GetStr()
{
char s[] = "hello word";
return s;
}
int main() {
//输入的数不能用数组读取,数组长度必须是常量(固定的)
char* p = GetStr();
printf("%s\n", p);//代码执行后会输出随机值,因为子函数的"hello word"在出去时就被销毁回收了,
//但是存它的那个空间还在所以是随机值a,子函数如酒店
return 0;
}
会输出如下:
malloc的运用:定义一个int类型的动态内存
类型*p=(强转类型*)malloc(n*sizeof(类型))
int main() {
int n;
scanf("%d", &n);
int* p = (int*)malloc(n * sizeof(int));//前面必须加(int*)来强转为int类型
for (int i = 0; i < n; i++) {
p[i] = i;
printf("%d", p[i]);
}
free(p);
return 0;
}
2、calloc:分配的内存都是0
calloc应用:
类型*q=(强转类型*)calloc(n,sizeof(类型)),与malloc有些不同
int main() {
int n = 10;
int* q = (int*)calloc(n, sizeof(int));
for (int i = 0; i < n; i++) {
printf("%d", q[i]);
}
printf("\n");
free(q);
return 0;
}
会如下输出:
3、realloc:扩容,容量修改
(类型*)realloc(p,新大小);
int main() {
int n = 10;
int* p = (int*)malloc(n * sizeof(int));
assert(p != 0);//当p != 0时才可执行下面代码,要引用<assert.h>文件
int i;
for (i = 0; i < n; i++) {
p[i] = i;
}//发现内存申请少了
p = (int*)realloc(p, 2 * n * sizeof(int));//将malloc扩大
free(p);
return 0;
}
4.free:释放动态内存,经常会出现程序崩溃的问题
内存崩溃:越界,指针移动,重复释放
(1)越界:常见情况是忘了乘sizeof,导致申请的空间不足,或本来就不足
(2)指针移动:
int main() {
int n = 10;
int* p = (int*)malloc(n * sizeof(int));
assert(p != 0);//当p != 0时才可执行下面代码,要引用<assert.h>文件
int i;
for (i = 0; i < n; i++) {
*p = 0;
p++;
}
free(p);
return 0;
}
(3)重复释放:
int main()
{
int n = 10;
int* p = (int*)malloc(n * sizeof(int));
free(p);
free(p);//崩溃
int arr[10];
free(arr);//不可以
return 0;
}