建设网站需要两种服务支持,wordpress 文章不显示,以下工具属于网站设计工具的是,微信公众号推广营销文章目录 前言一、为什么存在动态内存分配二、动态内存开辟函数的介绍1.malloc2.calloc3.realloc4.free 三、动态内存开辟中的常见错误1.误对NULL进行解引用操作2.对于动态开辟的空间进行了越界访问3.对于非动态开辟的内存进行了free操作4.只free掉动态开辟内存的一部分5.多次f… 文章目录 前言一、为什么存在动态内存分配二、动态内存开辟函数的介绍1.malloc2.calloc3.realloc4.free 三、动态内存开辟中的常见错误1.误对NULL进行解引用操作2.对于动态开辟的空间进行了越界访问3.对于非动态开辟的内存进行了free操作4.只free掉动态开辟内存的一部分5.多次free已经释放的空间内存 四、总结 添加链接描述
前言
大家好呀时隔好几天小小樊又来为大家分享C语言学习啦今天为大家分享一下自己对于动态内存管理的理解
一、为什么存在动态内存分配
对于栈上开辟的空间
空间开辟大小是固定的。数组在申明的时候必须指定数组的长度它所需要的内存在编译时分配。但是对于空间的需求不仅仅是上述的情况。有时候我们需要的空间大小在程序运行的时候才能知道那数组的编译时开辟空间的方式就不能满足了
这时就需要在堆区矩形动态内存开辟了
二、动态内存开辟函数的介绍
1.malloc
大家先看一下库中对于他的说明
函数功能开辟内存块 参数size_t:需要申请的字节数 返回值申请失败返回空指针申请成功返回指向申请该空间首地址的指针头文件stdlib.h 注意返回指针的类型是void*,这时候需要你把该指针强制类型转化为你想要的类型这样方便访问以及解引用malloc申请来的空间是连续的但是多次malloc来的是不连续的 malloc的使用
int main()
{int*p(int*) malloc(40);//申请了40个字节强制转化为int*类型指针if (p NULL)//如果返回空指针的话申请失败{perror(malloc:);//打印错误信息return 1;//非正常退出}for (int i 0; i 10; i){*(p i) i;//对每一个四个字节大小的元素赋值这里*pi的本质就是p[i];printf(%d, *(p i));//打印每个元素}return 0;//程序正常退出}2.calloc
大家先看一下库中对于他的说明 功能申请一个数组在内存中并且初始化为0 参数size_t num申请数组元素的个数size_t size每个元素的字节大小 返回值申请失败返回空指针申请成功返回指向申请该空间首地址的指针头文件stdlib.h calloc函数的使用
int main()
{int i 0;int*p(int*) calloc(10,sizeof(int));//申请10个元素每个元素字节大小4if (p NULL)//如果返回空指针的话申请失败{perror(calloc:);//打印错误信息return 1;//非正常退出}for (int i 0; i 10; i){printf(%d , *(p i));//打印初始化的值}free(p);p NULL;return 0;}malloc和calloc的区别 与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0
3.realloc
大家先看一下库中对于他的说明 功能内存块的扩容 参数第一个参数接收要扩容内存块的首地址扩容后总字节大小包括原来的字节大小 头文件stdlib.h 初始扩容的空间为空则realloc和malloc的用法一模一样 返回值扩容后空间的首地址 realloc函数的使用
int main()
{int* p (int*)malloc(40);//申请了40个字节强制转化为int*类型指针if (p NULL)//如果返回空指针的话申请失败{perror(malloc:);//打印错误信息return 1;//非正常退出}for (int i 0; i 10; i)//循环打印扩容前的元素{*(p i) i;printf(%d , *(p i));}int* ptr (int*)realloc(p, 80);//原空间够用ptrp,不够用的话ptr存放新地址if (ptr ! NULL)//扩容成功{p ptr;//原空间够用ptrp,不够用的话ptr存放新地址重新将新地址给p}for (int i 10; i 20; i)//扩容后新空间的{*(p i) i;printf(%d , *(p i));}free(p);p NULL;return 0;
}4.free
大家先看一下库中对于他的说明 功能释放内存块 参数指针接收要释放内存块的首地址 头文件stdlib.h 返回值无
注意 当p所指向的申请的空间释放时p指针指向随机位置p变成野指针所以我们要在释放后将其置为空
如果我们不释放动态内存申请的内存的时候程序结束动态申请内存由操作系统自动回收如果不用free函数释放申请好的空间就会在程序运行结束前一直存在于堆中造成内存泄漏
三、动态内存开辟中的常见错误
1.误对NULL进行解引用操作
比如
int main()
{int* p (int*)malloc(1000);int i 0;if (p NULL){return 1;}for (i 0; i 250; i){*(p i) i;}free(p);p NULL;return 0;
}当开辟内存失败时会返回空这时容易造成此错误。 解决方法开辟内存后进行判断如上面代码中的 if 判断
2.对于动态开辟的空间进行了越界访问
int main()
{int* p (int*)malloc(100);int i 0;if (p NULL){return 1;}for (i 0; i 25; i)//越界访问{*(p i) i;}free(p);p NULL;return 0;
}解决方法人为进行检查是否越界
3.对于非动态开辟的内存进行了free操作
int main()
{int a 10;int* p a;free(p);p NULL;return 0;
}4.只free掉动态开辟内存的一部分
int main()
{int* p (int*)malloc(100);if (p NULL){return 1;}int i 0;for (i 0; i 10; i){*p i;p;}free(p);p NULL;return 0;
}解决方案 别改变保存动态开辟空间首地址的指针变量使用时可以采用中间变量的方法 例如
int main()
{int* p (int*)malloc(100);if (p NULL){return 1;}int i 0;for (i 0; i 10; i){*(pi) i;printf(%d , *(p i));}free(p);p NULL;return 0;
}5.多次free已经释放的空间内存
int main()
{int* p malloc(40);if (p NULL){return 1;}free(p);free(p);p NULL;return 0;
}四、总结
本次内容到这里就分享完啦如果大家觉得对自己有帮助的话还请大家点个赞呀有分享不对的地方还恳请大家指正谢谢大家的阅读