在讲内存分配前,咱来聊一下为什么会有内存分配这个概念呢,大家都知道C语言当中是有着许多的数据类型,使用这些数据类型就会在内存上开辟其相对应的空间,那既然会开辟相应的空间,为什么还会有内存分配呢,我们会发现C语言分配内存空间,是已经被固定好了的,固定开辟多少空间,但是这样开辟空间会不会太死板了呢,如果我用不上这些空间呢,这样会导致内存的利用率很低,有没有一种,我需要多少空间,就开辟多少空间的方法呢,这个时候C语言就为我们引进了动态内存分配的这个概念,顾名思义,就是你想分配多少空间就分配多少空间,下边我们来一起了解一下怎样在内存上开辟我们想要的空间
(注意:使用这些函数都需要包含#include<stdlib.h>这个头文件)
函数向内存申请⼀块连续可⽤的空间,并返回指向这块空间的指针(由于不知道你要申请的类型,使用返回值为void*)
所以一个malloc的使用可以分为以下几步:
- #include <stdlib.h>
- int main()
- {
- int* p = (int*)malloc(sizeof(int) * 5); //向内存申请5个int型的内存空间
- if (p == NULL) //判断返回值是否为空
- {
- perror("malloc"); //为空,则报错malloc函数处有问题
- return 1;
- }
- free(p); //释放内存,在下边会说喔
- p = NULL; //将p指针赋为NULL,防止出现野指针
- return 0;
- }
在前边的代码当中,我们了解到free函数是专门用来释放动态申请的内存空间,同时也说明了它只能释放动态申请的内存空间,关于这一点兄弟们不要搞混咯
- int main()
- {
- int* p = (int*)malloc(sizeof(int) * 10);//申请10个int型元素
- if (p == NULL)
- {
- perror("malloc");
- return 1;
- }
- for (int i = 0; i < 10; i++) //对malloc申请的空间进行赋值
- {
- *(p + i) = i;
- }
- for (int i = 0; i < 10; i++) //输出
- {
- printf("%d ", *(p + i));
- }
- free(p); //释放空间
- p = NULL;
- return 0;
- }
- //执行结果
- 0 1 2 3 4 5 6 7 8 9
calloc
void* calloc (size_t num, size_t size);
下边我们来一段代码调试进行了解:
- int main()
- {
- int* p1 = (int*)calloc(10, sizeof(int));
- if (p1 == NULL)
- {
- perror("calloc");
- return 1;
- }
- free(p1);
- return 0;
- }
题解分析:
当你觉得动态内存申请的空间,不够使用的时候,这个时候就可以运用realloc函数对内存空间进行扩容,所以realloc函数是对动态内存空间进行扩容的
realloc
void* realloc (void* ptr, size_t size);
1. ptr 是要调整的内存地址
1. 原有的空间在扩容的时候,后边有足够的空间
2. 原有的空间在扩容的时候,后边没有足够的空间
- int main()
- {
- int* p = (int*)malloc(sizeof(int) * 10);
- if (p == NULL)
- {
- perror("malloc");
- return 1;
- }
- for (int i = 0; i < 10; i++)
- {
- *(p + i) = i;
- }
- for (int i = 0; i < 10; i++)
- {
- printf("%d ", *(p + i));
- }
- printf("\n");
- int* p1 = (int*)realloc(p,sizeof(int) * 15); //扩容5个int型
- if (p1 == NULL)
- {
- perror("realloc");
- return 2;
- }
- for (int i = 10; i < 15; i++)
- {
- *(p1 + i) = i;
- }
- for (int i = 0; i < 15; i++)
- {
- printf("%d ", *(p1 + i));
- }
- free(p1);
- p1 = NULL;
- return 0;
- return 0;
- }
- //执行结果
- 0 1 2 3 4 5 6 7 8 9
- 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
在c99中规定,一个结构体中最后的数组如果没有指定大小,则这个数组被称为柔性数组
柔性数组的特点:
- struct S
- {
- int a;
- char a1;
- int a3[];
- }q;
-
- int main()
- {
- printf("%结构体大小为:zd", sizeof(q)); //计算结构体大小,了解柔性数组是否分配了大小
- struct S* s = (struct S*)malloc(sizeof(struct S) + sizeof(int) * 5); //为a3数组分配了5个int型的空间
- return 0;
- }
题解分析:
申请一块动态内存空间后,对齐扩容,扩大柔性数组的内存空间,然后对柔性数组进行赋值,最后输出结构体中成员的值:
- //柔性数组
- struct S
- {
- int a;
- char a1;
- int a3[];
- }q;
- int main()
- {
- int ret = sizeof(struct S);
- struct S* p2 = (struct S*)malloc(sizeof(struct S));
-
- if (p2 == NULL)
- {
- perror("malloc");
- return 1;
- }
- p2->a = 100;
- p2->a1 = 48;
-
- struct S* p3 = (struct S*)realloc(p2, sizeof(struct S)+sizeof(int)*5); //扩容柔性数组的大小
- printf("%zd\n", sizeof(p3));
- if (p3 == NULL)
- {
- perror("realloc");
- return 2;
- }
- p2 = NULL;
- for (int i = 0; i < 5; i++)
- {
- p3->a3[i] = i;
- }
-
- printf("%d\n", p3->a);
- printf("%d\n", p3->a1);
- for (int i = 0; i < 5; i++)
- {
- printf("%d ", p3->a3[i]);
-
- }
- free(p3);
- p3 = NULL;
- return 0;
- }
- //执行结果
- 8
- 100
- 48
- 0 1 2 3 4
- int main()
- {
- int a = 10;
- int* p = &a;
- free(p); //free对非动态内存申请的空间进行释放
- return 0;
- }
执行结果:
- int main()
- {
- int* p = (int*)malloc(sizeof(int) * 5);//向内存动态申请5个int型空间
- if (p == NULL)
- {
- perror("malloc");
- return 1;
- }
- for (int i = 0; i < 6; i++) //向p执行的空间放入6个int型元素
- {
- *(p + i) = i;
- }
- return 0;
- }
执行结果:
(程序死循环加上报错)
- int main()
- {
- int* p = (int*)malloc(sizeof(int) * 5);
- if (p == NULL)
- {
- perror("malloc");
- return 1;
- }
- for (int i = 0; i < 5; i++)
- {
- *p = i;
- p++; //每执行一次p++,则p指向的地址加1
- }
- free(p);
- return 0;
- }
题解分析:
执行结果:
(程序死循环加上报错)
- int main()
- {
- int* p = (int*)malloc(sizeof(int) * 5);
- if (p == NULL)
- {
- perror("malloc");
- return 1;
- }
- free(p);
- free(p);
- return 0;
- }
执行结果:
(程序死循环加上报错)
什么意思呢,简单来讲,就是你申请了空间,但是没有及时的将空间释放掉,与上边多次释放刚好相反:
- int main()
- {
- int* p = (int*)malloc(sizeof(int) * 5);
- if (p == NULL)
- {
- perror("malloc");
- return 1;
- }
- //free(p); //为注释掉的内容
- //free(p);
- return 0;
- }
执行以后不会报错,但是会造成内存上的浪费
- int main()
- {
- int* p = (int*)malloc(INT_MAX*10);
- *p = 100;
- free(p);
- return 0;
- }
由于并没有判断p是否为NULL,当p为NULL时,就会发生以下报错:
(死循环直至程序崩溃)
(今日分享到此结束,如觉得对您有帮助,还请点赞关注支持一下,Thanks♪(・ω・)ノ!!!)