• 动态内存管理


         我们之前在申请空间时,都是一些固定空间。如果我们后面想调整空间的大小是办不到的。C语言提供了一些函数可以让我们实现这个操作(头文件<stdlib.h>,空间在堆区开辟)。

    目录

    malloc

    free

    calloc

    realloc

    常见动态内存错误

    1. 对NULL指针的解引用操作

    2. 对非动态开辟内存使用free释放

    3.使用free释放一块动态开辟内存的一部分

    4. 对同一块动态内存多次释放

    5. 动态开辟内存忘记释放(内存泄漏)


    malloc

    724743dce95043ff829bf735792d1192.png

         该函数的功能:开辟一段连续空间。

    • size是开辟多少个字节。
    • 该函数类型是void*,在使用时要根据实际情况进行类型转换。
    • 开辟成功返回指向这一块的指针,失败则返回NULL。
    1. #include
    2. #include
    3. int main()
    4. {
    5. int* arr = (int*)malloc(5 * sizeof(int));
    6. if (arr == NULL)//判断开辟是否成功
    7. {
    8. printf("开辟失败");
    9. return;
    10. }
    11. return 0;
    12. }

         注意:malloc开辟的空间是未初始化的。

    free

    c1585a5b5dad46d39210bab5f2a2e3db.png

         该函数的功能:释放动态开辟的内存。

    • ptr是指向动态开辟空间的地址。
    • 如果ptr是NULL则不做任何事情。
    1. #include
    2. #include
    3. int main()
    4. {
    5. int* arr = (int*)malloc(5 * sizeof(int));
    6. if (arr == NULL)
    7. {
    8. printf("开辟失败");
    9. return;
    10. }
    11. free(arr);
    12. arr = NULL;//避免出现野指针
    13. return 0;
    14. }

         注意:动态开辟的空间一定要释放,否则会造成内存泄露。这是很严重的问题!

    calloc

    8c4a1328e9f7421781a73564a6e65aff.png

        该函数的功能:为 num 个大小为 size 的元素开辟一块空间。

        calloc和malloc的功能几乎一样,只是calloc会把空间的每个字节初始化为0。

    1. #include
    2. #include
    3. int main()
    4. {
    5. int* arr = (int*)calloc(5 , sizeof(int));
    6. if (arr == NULL)
    7. {
    8. printf("开辟失败");
    9. return;
    10. }
    11. free(arr);
    12. arr = NULL;
    13. return 0;
    14. }

    realloc

    772ecc37fc3e470c8cd573395a4ad574.png

        该函数的功能:对动态开辟内存的大小进行调整。

    • ptr 是要调整的内存的地址。ptr可以是NULL这时候就是创建空间。
    • size 调整之后的总字节数。

        函数在调整内存空间时有两种情况:

    • 情况1:原有空间之后有足够大的空间

              要扩展内存就直接原有内存之后直接追加空间,返回原地址即可。

    67611920a77d49399a04ca225213ca49.png

    • 情况2:原有空间之后没有足够大的空间

              它会在堆区上找一块合适的空间使用,返回新地址。原来的旧空间会被释放。

    36ced899157c439c92a502bcfab6c0ff.png

              如果找不到合适的空间返回NULL。

    1333c443666c4b6db7f83453194b61f0.png

    1. #include
    2. #include
    3. int main()
    4. {
    5. int* arr = (int*)malloc(5 * sizeof(int));
    6. if (arr == NULL)
    7. {
    8. printf("开辟失败");
    9. return;
    10. }
    11. int* new = (int*)realloc(arr, 10 * sizeof(int));
    12. if (new == NULL)
    13. {
    14. printf("开辟失败");
    15. return;
    16. }
    17. arr = new;
    18. free(arr);
    19. arr = NULL;
    20. return 0;
    21. }

    常见动态内存错误

    1. 对NULL指针的解引用操作

         如果开辟失败。我们对它进行解引用就会出现这种情况,所以我们在使用这块空间之前要检查一下是否为NULL。

    2. 对非动态开辟内存使用free释放

         free只能对动态开辟的空间进行释放。

    3.使用free释放一块动态开辟内存的一部分

         传入free的参数要是动态开辟空间的首地址,如果不是首地址就会发生内存泄漏。

    4. 对同一块动态内存多次释放

         同一块内存只能释放一次。为了避免多次释放,我们在释放后把它置为NULL。即使后面我们再次释放这块空间也不会发生错误。

    5. 动态开辟内存忘记释放(内存泄漏)

         动态开辟的内存在使用完后一定要释放,如果不释放会造成严重的后果。


         好了讲到这儿就差不多讲完了,希望你能有所收获。如果有错误的地方请及时指出,有什么不懂的地方可以私信我哈,如果觉得不错那就点点赞吧!

  • 相关阅读:
    STM TIM(二)输出比较
    【PyQt】调整子控件的层级以调整绘制的先后顺序
    微信小程序订阅消息前后端示例
    基于JavaSwing开发超市管理系统 课程设计 大作业
    正则表达式实战
    分数阶混沌系统李雅普指数和分岔图
    vant_ CountDown倒计时
    基于上一篇博客,用阻塞队列实现异步下单
    sql语句 如果为空值显示为0
    软件代码坏味道之滥用switch
  • 原文地址:https://blog.csdn.net/2301_80662872/article/details/138082926