网站开发作品,Wordpress多重筛选插件,手机主题制作软件,网站建设要求报告C语言程序设计笔记---029 C语言之动态内存管理1、介绍动态内存管理2、动态内存函数的介绍2.1、malloc和free函数2.2、calloc函数2.3、realloc函数 3、动态内存管理过程中#xff0c;一些常见的错误3.1、对NULL指针的解引用操作3.2、对动态内存开辟的空间的越界访问3.3、对非动… C语言程序设计笔记---029 C语言之动态内存管理1、介绍动态内存管理2、动态内存函数的介绍2.1、malloc和free函数2.2、calloc函数2.3、realloc函数 3、动态内存管理过程中一些常见的错误3.1、对NULL指针的解引用操作3.2、对动态内存开辟的空间的越界访问3.3、对非动态开辟内存使用了free函数3.4、使用free释放一块动态开辟内存的一部分3.5、对同一块动态内存多次释放3.6、动态开辟内存忘记释放导致内存泄漏 4、柔性数组介绍4.1、柔性数组的使用 5、结语 C语言之动态内存管理
前言 通过C语言自定义类型的知识这篇将对动态内存管理进行深入学习和巩固相关的知识。
/知识点汇总/
1、介绍动态内存管理
概念动态内存管理是指在程序运行时根据需要动态地分配和释放内存空间的过程。 那么什么时候需要应用到动态分配内存呢 通常来说我们经常使用的数组一般都是定长数组因为在内存中申请的空间是固定的 比如当我明确知道需要采集100个人的成绩的时候那么就可以使用指明长度的数组 int arr[101] 那么当我不知道采集多少人的时候长度定1000可能采集全校学生的信息就太小又可能采集一个班级又太大导致分配的空间资源得不到很好的利用甚至浪费。 所以此时根据C语言标准它赋予程序员一种权力能够动态申请和管理内存空间 目的是合理的利用存储空间使得效率更高让我们有能力灵活的运用而得心应手。 值得注意的是动态内存管理的操作是在 堆区 上进行的操作的
2、动态内存函数的介绍
在C/C中动态内存管理主要通过malloc、calloc、realloc和free等函数来实现。 其中malloc函数用于分配指定大小的内存空间calloc函数用于分配指定数量和大小的内存空间并初始化为0realloc函数用于重新分配已经分配的内存空间而free函数则用于释放已经分配的内存空间。
2.1、malloc和free函数
malloc函数: 原型void* malloc(size_t size); 头文件stdlib.h 功能向内存申请一块连续可用的空间并返回指向这块空间的指针 返回值 如果开辟成功则返回一个指向开辟好的空间的指针 如果开辟失败则返回一个NULL指针因此malloc的返回值一定要判定检查否则可能为野指针 free函数 原型void free( void memblock ); 头文件stdlib.h 功能释放申请的内存空间通常与申请内存空间的函数malloc()结合使用可以释放由 malloc()、calloc()、realloc() 等函数申请的内存空间。 补充 1、返回值的类型是void,所以malloc函数并不确定开辟空间的类型由使用者自己决定。 2、如果参数size为0,malloc的行为是标准是未定义的取决于当前的编译器。 3)、当然我们申请空间也存在失败的情况所以需要考虑各种情况做到代码的严谨性。 示例如下所示
#include stdio.h
#include stdlib.h
#include limits.h//调用INT_MAX需申明的头文件
int main()
{//申请一块空间用来存放10个整型int* p (int*)malloc(10 * sizeof(int));if (p NULL){perror(malloc);//开辟空间失败打印错误原因return 1;}//当申请的空间太大或被占用就会出现失败的情况int* p2 (int*)malloc(INT_MAX*4);//INT_MAX开辟一个整型最大值的空间if (p2 NULL){perror(malloc);//开辟空间失败打印错误原因return 1;}return 0;
}关于动态内存的释放 分为两种释放方式 1.主动释放通过free函数主动释放空间 2.被动释放程序退出后被操作系统回收释放 正常情况下谁申请谁释放万一自己不释放也得交代给别人释放 补充 1)、如果参数ptr指向的空间不是动态开辟的那么free函数的行为就是C标准未定义的 2)、如果参数ptr是NULL指针则函数什么事都不做即无用功
#include stdio.h
#include stdlib.hint main()
{//申请一块空间用来存放10个整型int* p (int*)malloc(10 * sizeof(int));if (p NULL){perror(malloc);//开辟空间失败打印错误原因return 1;}//动态内存的使用int i 0;for (i 0; i 10; i){*(p i) i;}for (i 0; i 10; i){printf(%d , *(p i));}//释放动态内存空间 -- freefree(p);p NULL;//必须将p指针开辟的空间置为空避免导致野指针return 0;
}2.2、calloc函数
原型void* calloc(size_t num,size_t size); 功能 为Num个大小为size的元素开辟一块空间并且把空间的每一个字节初始化为0 与malloc函数的区别只在于callloc会返回地址之前把申请的空间的每一个字节初始化为全0 头文件stdlib.h 与malloc函数对比 1)、功能对比calloc会把每一个字节初始化为全0而malloc不会初始化 2)、函数原型对比 void* calloc(size_t num,size_t size); void* malloc(size_t size); 示例如下
#include stdio.h
#include stdlib.h
int main()
{int* p (int*)malloc(10 * sizeof(int));if (p NULL){perror(malloc);return 1;}//打印int i 0;for (i 0; i 10; i){printf(%d , *(p i));//随机值堆区 --- 不是ccccc}//释放free(p);p NULL;int* p2 (int*)calloc(10 , sizeof(int));if (p2 NULL){perror(calloc);return 1;}//打印int i 0;for (i 0; i 10; i){printf(%d , *(p2 i));//0堆区 --- calloc初始化}//释放free(p2);p2 NULL;return 0;
}2.3、realloc函数
原型void* realloc(void* ptr,size_t size); 功能使得动态内存管理更灵活即对动态内存空间进行调整 头文件stdlib.h 返回值 返回的是一个void类型的指针调用成功。这就要求在你需要的时候进行强制类型转换 返回NULL当需要扩展的大小第二个参数为0并且第一个参数不为NULL时。此时原内存变成“free游离”的了。 返回NULL当没有足够的空间可供扩展的时候。此时原内存空间的大小维持不变。 realloc函数开辟空间的多种情况 1.特殊情况后续空间可能被占用不能直接增加 那么realloc函数会找一块新的空间足够一次性能全方进所有数据的空格并会将旧空间的数据一同拷贝到新空间 其次完成新空间开辟拷贝后就释放旧空间最后返回指向新空间的地址/指针 2.正常情况原有空间之后有足够大的空间返回调整之后的内存起始地址 示例如下所示
#include stdio.h
#include stdlib.hint main()
{int* p (int*)calloc(10, sizeof(int));if (p NULL){perror(calloc);return 1;}int i 0;//使用空间存储数据for (i 0; i 10; i){p[i] i;}//打印for (i 0; i 10; i){printf(%d , *(p i));//0堆区 --- calloc初始化}//空间不够时调整空间为20个整型的空间int* ptr (int*)realloc(p, 20 * sizeof(int));if (ptr ! NULL)//开辟空间成功{p ptr;}//释放free(p);return 0;
}realloc函数开辟空间的特殊情况后续空间可能被占用不能直接增加
#include stdio.h
#include malloc.hint main(int argc, char* argv[]){char *p,*q;p (char *)malloc(10);q p;p (char *)realloc(p,10);printf(p0x%x/n,p);printf(q0x%x/n,q);return 0;}输出结果:realloc后内存地址发生了变化 p0x431a70 q0x431a70
#include stdio.h
#include malloc.h
int main(int argc, char* argv[])
{char *p,*q;p (char *)malloc(10);q p;p (char *)realloc(p,1000);printf(p0x%x/n,p);printf(q0x%x/n,q);return 0;
}输出结果:realloc后内存地址发生了变化 p0x351c0 q0x431a70
realloc函数平替mallloc函数的技巧使用
#include stdio.h
#include stdlib.h
int main()
{int* p (int*)realloc(NULL, 40);//等价 -- malloc(40);if (p NULL){perror(realloc);return 1;}free(p);p NULL;return 0;
}3、动态内存管理过程中一些常见的错误
在动态内存管理过程中需要注意避免一些常见的错误 如对NULL指针的解引用操作、对动态开辟的内存进行越界访问、对非动态开辟的内存free、使用free释放动态内存的一部分、对同一块动态内存多次释放等。
3.1、对NULL指针的解引用操作
#include stdio.h
int main()
{int* p (int*)malloc(40);//当此时不作返回值判断时则有可能是对空指针进行操作非法访问//野指针*p 20;//解决办法添加判断后执行//if (p NULL)//{// //...//}return 0;
}3.2、对动态内存开辟的空间的越界访问
#include stdio.h
#include stdlib.h
int main()
{int* p (int*)calloc(10, sizeof(int));if (p NULL){perror(calloc);return 1;}int i 0;//越界访问对开辟的空间越界访问了for (i 0; i 10; i){p[i] i;}for (i 0; i 10; i){printf(%d , *(p i));}free(p);p NULL;return 0;
}3.3、对非动态开辟内存使用了free函数
#include stdio.h
#include stdlib.h
int main()
{int a 10;int* p a;//对非动态内存空间释放空间 -- errorfree(p);p NULL;return 0;
}3.4、使用free释放一块动态开辟内存的一部分
#include stdio.h
#include stdlib.h
int main()
{int* p (int*)calloc(10, sizeof(int));if (p NULL){perror(calloc);return 1;}int i 0;for (i 0; i 5; i){*p i;p;}// 0 1 2 3 4 0 0 0 0 ---- errorfor (i 0; i 10; i){printf(%d , *(p i));}free(p);//只释放了一部分动态开辟的内存空间//更好的办法是引用另一个指针变量使得始终保存p的起始地址p NULL;return 0;
}3.5、对同一块动态内存多次释放
#include stdio.h
#include stdlib.h
int main()
{int* p (int*)malloc(40);if (p NULL){perror(malloc);return 1;}//...free(p);//error//解决办法始终与free搭配释放后置为空指针//p NULL;//有了空指针以免后面再次释放时及时报错提醒//....free(p);p NULL;return 0;
}3.6、动态开辟内存忘记释放导致内存泄漏
#include stdio.h
#include stdlib.h
void test()
{int* p (int*)malloc(40);if (p NULL){perror(malloc);return 1;}//不释放 -- error//....//解决办法1谁申请谁及时释放//free(p);//p NULL;
}
int main()
{test();//在函数内开辟的动态内存不释放//解决办法2使void* test 设置返回值---int* test(),返回p//用指针变量接收p//int* ret test();// free(ret);// ....while (1);return 0;
}4、柔性数组介绍
概念C99标准中规定结构中的最后一个元素允许是未知大小的数组这就叫做柔性数组成员柔性数组是结构体的成员 比如
typedef struct st_type
{int i;int a[0];//柔性数组成员
}st_type;
4.1、柔性数组的使用
方法一使用数组的方法
#include stdio.h
#include stdlib.h
struct S
{char c;//1int i;//4int arr[];//未知大小的数组 -- 柔性数组成员
};
int main()
{//printf(%zd\n, sizeof(struct S));//8sizeof返回的这种结构大小不包括柔性数组的内存//即不包括柔性数组的内存大小。不做计算struct S* ps (struct s*)malloc(sizeof(struct S) 20);if (ps NULL){perror(malloc);return 1;}ps-c w;ps-i 100;int i 0;for (i 0; i 5; i){ps-arr[i] i;}//打印for (i 0; i 5; i){printf(%d , ps-arr[i]);}//如果空间不够,就可使用柔性数组和内存函数搭配灵活使用动态内存struct S* ptr (struct S*)realloc(ps, sizeof(struct S) 40);if (ptr ! NULL){ps ptr;}else{perror(realloc);return 1;}//释放free(ps);ps NULL;return 0;
}方法二使用指针的方法
#include stdio.h
#include stdlib.h
struct S
{char c;//1int i;//4int* data;
};
int main()
{struct S* ps (struct s*)malloc(sizeof(struct S) 20);if (ps NULL){perror(malloc1);return 1;}ps-c w;ps-i 100;ps-data (int*)malloc(20);if (ps-data NULL){perror(malloc2);return 1;}int i 0;for (i 0; i 5; i){ps-data[i] i;}//打印for (i 0; i 5; i){printf(%d , ps-data[i]);}//如果空间不够,就可使用柔性数组和内存函数搭配灵活使用动态内存int* ptr (int*)realloc(ps-data, 40);if (ptr NULL){perror(realloc);return;}//释放free(ps-data);ps-data NULL;free(ps);ps NULL;return 0;
}小结 1.结构中的柔性数组成员前面必须至少一个其他成员 2.sizeof返回的这种结构大小不包括柔性数组的内存 3.包含柔性数组成员的结构用malloc函数进行内存的动态分配并且分配的内存应该大于结构的大小以适应柔性数组的预期大小 对比两种方法 柔性数组加动态内存与相比指针加动态内存的方法指针的方法更好 1.方便内存释放 2.有利于访问速度
5、结语
掌握动态内存管理用于利于我们把知识嚼碎的消化从而更好地理解和控制内存提高程序的效率和性能减少内存碎片和错误增强程序的灵活性和适应性。同时也要避免错误和内存泄漏的可能性。 名人名言分享 “我愿意投入时间和精力去学习因为我知道这将使我在未来的生活中受益。” — 爱因斯坦 “生活就像海洋只有意志坚强的人才能到达彼岸。” — 马克思 “只有那些敢于相信自己内心有某种比生存更重要的东西的人才能过上所想象的那种充满快乐的生活。” — 契诃夫 文章转载自: http://www.morning.gkmwx.cn.gov.cn.gkmwx.cn http://www.morning.tpyjr.cn.gov.cn.tpyjr.cn http://www.morning.rkjz.cn.gov.cn.rkjz.cn http://www.morning.hxwrs.cn.gov.cn.hxwrs.cn http://www.morning.bhwz.cn.gov.cn.bhwz.cn http://www.morning.nypsz.cn.gov.cn.nypsz.cn http://www.morning.kflzy.cn.gov.cn.kflzy.cn http://www.morning.wbqk.cn.gov.cn.wbqk.cn http://www.morning.yhdqq.cn.gov.cn.yhdqq.cn http://www.morning.tbcfj.cn.gov.cn.tbcfj.cn http://www.morning.rrcrs.cn.gov.cn.rrcrs.cn http://www.morning.jpydf.cn.gov.cn.jpydf.cn http://www.morning.srtw.cn.gov.cn.srtw.cn http://www.morning.ssfq.cn.gov.cn.ssfq.cn http://www.morning.slzkq.cn.gov.cn.slzkq.cn http://www.morning.yrccw.cn.gov.cn.yrccw.cn http://www.morning.bfnbn.cn.gov.cn.bfnbn.cn http://www.morning.kzslk.cn.gov.cn.kzslk.cn http://www.morning.yzygj.cn.gov.cn.yzygj.cn http://www.morning.ztqyj.cn.gov.cn.ztqyj.cn http://www.morning.pswzc.cn.gov.cn.pswzc.cn http://www.morning.qzqfq.cn.gov.cn.qzqfq.cn http://www.morning.rqsnl.cn.gov.cn.rqsnl.cn http://www.morning.qqbw.cn.gov.cn.qqbw.cn http://www.morning.dhnqt.cn.gov.cn.dhnqt.cn http://www.morning.tgbx.cn.gov.cn.tgbx.cn http://www.morning.cthkh.cn.gov.cn.cthkh.cn http://www.morning.qtyfb.cn.gov.cn.qtyfb.cn http://www.morning.dcccl.cn.gov.cn.dcccl.cn http://www.morning.nytpt.cn.gov.cn.nytpt.cn http://www.morning.llxqj.cn.gov.cn.llxqj.cn http://www.morning.bljcb.cn.gov.cn.bljcb.cn http://www.morning.prgnp.cn.gov.cn.prgnp.cn http://www.morning.kwyq.cn.gov.cn.kwyq.cn http://www.morning.bmqls.cn.gov.cn.bmqls.cn http://www.morning.yqqgp.cn.gov.cn.yqqgp.cn http://www.morning.tygn.cn.gov.cn.tygn.cn http://www.morning.pxjp.cn.gov.cn.pxjp.cn http://www.morning.lzbut.cn.gov.cn.lzbut.cn http://www.morning.jklns.cn.gov.cn.jklns.cn http://www.morning.rbkl.cn.gov.cn.rbkl.cn http://www.morning.c7510.cn.gov.cn.c7510.cn http://www.morning.bzfwn.cn.gov.cn.bzfwn.cn http://www.morning.fncgw.cn.gov.cn.fncgw.cn http://www.morning.ndltr.cn.gov.cn.ndltr.cn http://www.morning.gjlst.cn.gov.cn.gjlst.cn http://www.morning.qjrjs.cn.gov.cn.qjrjs.cn http://www.morning.wnnlr.cn.gov.cn.wnnlr.cn http://www.morning.xbtlt.cn.gov.cn.xbtlt.cn http://www.morning.tjsxx.cn.gov.cn.tjsxx.cn http://www.morning.phlrp.cn.gov.cn.phlrp.cn http://www.morning.sqnxk.cn.gov.cn.sqnxk.cn http://www.morning.jcfg.cn.gov.cn.jcfg.cn http://www.morning.sgfnx.cn.gov.cn.sgfnx.cn http://www.morning.msgrq.cn.gov.cn.msgrq.cn http://www.morning.bctr.cn.gov.cn.bctr.cn http://www.morning.nhpgm.cn.gov.cn.nhpgm.cn http://www.morning.hxljc.cn.gov.cn.hxljc.cn http://www.morning.qnbgh.cn.gov.cn.qnbgh.cn http://www.morning.rkfxc.cn.gov.cn.rkfxc.cn http://www.morning.dswtz.cn.gov.cn.dswtz.cn http://www.morning.dgpxp.cn.gov.cn.dgpxp.cn http://www.morning.nlysd.cn.gov.cn.nlysd.cn http://www.morning.brkrt.cn.gov.cn.brkrt.cn http://www.morning.kkjlz.cn.gov.cn.kkjlz.cn http://www.morning.zcrjq.cn.gov.cn.zcrjq.cn http://www.morning.crqbt.cn.gov.cn.crqbt.cn http://www.morning.nftzn.cn.gov.cn.nftzn.cn http://www.morning.jqbmj.cn.gov.cn.jqbmj.cn http://www.morning.mqxzh.cn.gov.cn.mqxzh.cn http://www.morning.nxdqz.cn.gov.cn.nxdqz.cn http://www.morning.wnmdt.cn.gov.cn.wnmdt.cn http://www.morning.tdnbw.cn.gov.cn.tdnbw.cn http://www.morning.nrftd.cn.gov.cn.nrftd.cn http://www.morning.nsyzm.cn.gov.cn.nsyzm.cn http://www.morning.qwlml.cn.gov.cn.qwlml.cn http://www.morning.fhjnh.cn.gov.cn.fhjnh.cn http://www.morning.jpfpc.cn.gov.cn.jpfpc.cn http://www.morning.nqpy.cn.gov.cn.nqpy.cn http://www.morning.thwcg.cn.gov.cn.thwcg.cn