🧸🧸🧸各位大佬大家好,我是猪皮兄弟🧸🧸🧸
今天带来的内容是动态内存分配。
这里是下面要讲的知识内容🥳🥳🥳
文章目录
一、🚒前言:为什么存在动态内存分配
为什么存在动态内存分配?
int val = 20;//在栈空间上开辟四个字节
char arr[10]={0};//在栈空间上开辟十个字节的连续空间
但是这两种开辟方式都有两个特点
1.空间开辟大小是固定的
2.数组在声明的时候,必须指定数组的长度,它所需要的内存在编译时分配。
二、🚀内存中常见的区域划分
在内存中,常见的区域有
栈区、堆区、静态区、常量区等等
局部变量是存放在栈区上的,栈区的使用习惯是先用高地址再用低地址
静态变量是存放在静态区上的
而动态内存开辟的空间,就是在堆区上开辟的,
比如说malloc,realloc,calloc
三、🚀动态内存开辟函数
1、⛄malloc
malloc的使用需要引头文件 stdlib.h 或者 malloc.h
malloc的开辟会在堆区上找一块空间,开辟失败则会返回空指针
可以看到,malloc的返回类型是void*,所以,在接收返回值时,需要强制类型转换
malloc的用法:
int main()
{
//int arr1[10];//40个字节
//char arr2[40];//40个字节
void*malloc(size_t);
//int* arr3 = (int*)malloc(sizeof(int) * 10);//在堆区申请
//char* arr4 = (char*)malloc(sizeof(char) * 40);
int* p = (int*)malloc(sizeof(int) * 10);
int* ptr = p;
if (p==NULL)
{
perror("malloc");
return 1;
}
int i = 0;
for (int i = 0; i < 10; i++)
{
*p = i;
p++;
printf("%d ",*p);
}
free(ptr);
ptr = NULL;
//free了之后这块空间已经不属于我们了,但是ptr还是指向这块空间,很危险,
//所以,通常free掉之后,把指向这块空间的这个指针置为NULL空指针
if (ptr != NULL)
{
*ptr = 100;
}
return 0;
}
值得注意的是:
1.动态开辟的空间就要主动释放,还给操作系统,不然很可能导致内存泄漏的问题。
2.malloc(0)是未定义的,出现的后果取决于编译器.
3.如果参数ptr指向的空间不是动态开辟的 ,那么free函数的行为是未定义的。
4.free(NULL);的结果是无事发生。
5.释放过的空间再释放也是会出问题的。,因为free需要的是释放空间的起始地址,如果被释放掉了,这一块空间是不属于我们的,会出现野指针的问题
2、⛄calloc
calloc与malloc的区别不大,就是开辟之后初始化为0
3、⛄realloc
realloc用于调节开辟空间的大小
1.想扩大的空间在后面大小足够
2.大小不足(已经被占用),realloc会在后面一个合适的区域选一个足够大小的空间来扩容
同时,会把之前的空间都拷贝到这个空间里面去,同时会把原来的空间free掉(同时这样做也会引起一些问题,比如数据过多就会影响性能,原空间可能有一定的浪费)
3.同时,realloc失败也返回空指针NULL
当动态内存开辟失败的时候,就应该结束程序了,因为后面的空间都不够了,无法继续程序逻辑的进行。
三、内存泄漏的问题
程序(进程)正常结束,就算程序里malloc没有free,也会自动释放掉
如果不是正常的结束,内存没有还给操作系统,以后内存就可能越来越少
而且,有些数据是需要长期运行的 ,比如说服务后台
还有就是嵌入式程序,内存本来就很少,泄漏一点点就更小了
四、一道烧脑题
五、🚀五彩斑斓的一些废话
创作不易,提前感谢各位老铁的一键三连,我会和大家一起进步,拿下offer。如果觉得这篇文章有什么帮助的话,👈👇👉点点点。谢谢大家的支持,你的支持就是我前进的动力!!!