了解了C语言中一些基础知识后,我们今天来了解一下C语言的内存开辟(动态开辟、静态开辟)。
静态开辟:
C语言是面向过程的语言,所以在每一个函数执行时,都会进栈,执行完后弹栈,这一点有点类似于我们在面向对象语言中的对象的作用域的概念。
int main(){
int i=0;
int *p=&i;
int arr[5];
//.....变量,指针,数组,结构体等,
return 0;
}
上述代码中定义的变量,都会在main函数执行完后,执行弹栈操作,释放栈区开辟的内存空间。
特别强调:
1)如果main函数调用了其他函数,其他函数同样需要完成进栈弹栈的操作,在栈区开辟的栈成员空间会被释放掉;
2)栈区可允许开辟的空间大小有限(大概2M,与平台有关);
3)静态开辟的内存大小是不能修改的;(尽量使用静态开辟,如果确实需要动态变化,再使用堆区)
动态开辟:
野指针:没有指向任何地址的指针,就是野指针,例如未给指针赋值;
悬空指针:指针指向的内存地址被释放掉,没有指向NULL的指针就是悬空指针
1)使用 malloc 在堆区开辟的内存空间
int main(){
int * p;//野指针
int * arr = malloc(1 * 1024 * 1024); // 堆区开辟 4M
printf("dynamicAction函数,arr自己的内存地址:%p,堆区开辟的内存地址:%p\n", &arr, arr);
//***** 堆区开辟的空间一定要free ,并将指针指向NULL
free(arr); // 释放掉
arr = NULL; // 重新指向一块内存地址00000,不赋值就是悬空指针了
printf("悬空指针的地址:%p\n", arr); //
return 0;
}
动态开辟使用场景(根据用户需求来开辟):
int main(){
int num;
printf("请输入数的个数:");
// 获取用户输入的值
scanf("%d", &num);
// 动态开辟 用户输入的值 空间的大小 【堆区】
int * arr = malloc(sizeof(int) * num);
int print_num;
// 循环接收
for (int i = 0; i < num; ++i) {
printf("请输入第%d个的值:", i);
// 获取用户输入的值
scanf("%d", &print_num);
arr[i] = print_num;
printf("每个元素的值:%d, 每个元素的地址:%p\n", *(arr + i), arr + i);
}
return 0;
}
2) realloc 动态开辟之使用
说明:
1)realloc 是在源堆空间地址上追加开辟的意思;
2)返回的指针与第一个参数指针指向的是同一个地址;第一个参数是源空间地址,第二个参数是需要开辟的总大小
3)动态开辟的地址,都需要free,并指向NULL,但是重复free会crash, 所以在free之前要做判断
int main(){
int num;
printf("请输入动态开辟的的个数:");
// 获取用户输入的值
scanf("%d", &num);
// 动态开辟 用户输入的值 空间的大小 【堆区】
int *arr = malloc(sizeof(int) * num);
printf("malloc函数返回的指针地址:%p", arr);
//给元素赋值
for (int i = 0; i < num; i++) {
*(arr + i) = i + 100;
}
printf("**********打印动态开辟的元素信息*************\n");
for (int i = 0; i < num; i++) {
printf("第 %d 个元素的值:%d, 地址:%p\n", i, arr[i], arr + i);
}
int new_num;
printf("请输入重新动态开辟的的个数:\n");
// 获取用户输入的值
scanf("%d", &new_num);
int *new_arr = realloc(arr, sizeof(int) * (num + new_num));
printf("realloc函数返回的指针地址:%p", new_arr);
if (new_arr) {
for (int i = num; i < num + new_num; i++) {
*(new_arr + i) = 200 + i;
}
printf("**********重新开辟的元素信息*************\n");
for (int i = 0; i < num + new_num; i++) {
printf("第 %d 个元素的值:%d, 地址:%p\n", i, new_arr[i], new_arr + i);
}
}
if (new_arr) {
free(new_arr);
new_arr = NULL;
}
if (arr) {
free(arr);
arr = NULL;
}
}
//输出结果
/**
请输入动态开辟的的个数:3
malloc函数返回的指针地址:0000000000AD6CD0
**********打印动态开辟的元素信息*************
第 0 个元素的值:100, 地址:0000000000AD6CD0
第 1 个元素的值:101, 地址:0000000000AD6CD4
第 2 个元素的值:102, 地址:0000000000AD6CD8
请输入重新动态开辟的的个数:
3
realloc函数返回的指针地址:0000000000AD6CD0
**********重新开辟的元素信息*************
第 0 个元素的值:100, 地址:0000000000AD6CD0
第 1 个元素的值:101, 地址:0000000000AD6CD4
第 2 个元素的值:102, 地址:0000000000AD6CD8
第 3 个元素的值:203, 地址:0000000000AD6CDC
第 4 个元素的值:204, 地址:0000000000AD6CE0
第 5 个元素的值:205, 地址:0000000000AD6CE4
*/
网友评论