• malloc,calloc,realloc的使用方法和注意事项


    一,我们先来介绍一下今天的第一个函数malloc:

    参数:无符号整形。

    返回值:void*的指针,内存开创成功后返回的是内存的起始地址,如果失败,返回NULL;

    功能就是开辟指定大小的内存空间,但是不对该内存进行初始化,保留的是不确定的值。

    我们在使用该函数的时候要注意对malloc之后的返回值进行强制类型转换,以便达到我们的使用目的。

    接下来我们以一个例子来使用一下malloc

    1. #include
    2. #include
    3. #include
    4. int main()
    5. {
    6. //使用malloc开辟一块内存,并给该内存赋值。
    7. int* ptr = (int*)malloc(20);//开辟20个字节的空间
    8. int* p = ptr;
    9. //判断一下返回值是否正常
    10. if (p == NULL)
    11. {
    12. //显示一下错误信息,并介绍代码的运行
    13. strerror(errno);
    14. free(ptr);
    15. p = NULL;
    16. ptr = NULL;
    17. return 1;
    18. }
    19. for (int i = 0; i < 5; i++)
    20. {
    21. *p = i;
    22. p++;
    23. }
    24. for (int i = 0; i < 5; i++)
    25. {
    26. printf("%d ", *(ptr + i));
    27. }
    28. //释放
    29. free(ptr);
    30. ptr = NULL;
    31. p = NULL;
    32. return 0;
    33. }

    无论在使用那个动态内存函数开辟的空间,大家在最后使用之后一定要注意用free()释放,释放时使用的时内存的首地址,所以我上面使用了p来进行赋值操作,但是这有点繁琐了,使用一个指针也是能完成上面的要求的,下面说代码的优化:

    1. #include
    2. #include
    3. #include
    4. int main()
    5. {
    6. //使用malloc开辟一块内存,并给该内存赋值。
    7. int* ptr = (int*)malloc(20);//开辟20个字节的空间
    8. //判断一下返回值是否正常
    9. if (ptr == NULL)
    10. {
    11. //显示一下错误信息,并介绍代码的运行
    12. strerror(errno);
    13. //这里可以不进行释放,因为我使用了return程序结束之后,内存就释放掉了!
    14. //free(ptr);
    15. //ptr = NULL;
    16. return 1;
    17. }
    18. for (int i = 0; i < 5; i++)
    19. {
    20. //这样ptr的值就没有改变。
    21. *(ptr + i) = i;
    22. }
    23. for (int i = 0; i < 5; i++)
    24. {
    25. printf("%d ", *(ptr + i));
    26. }
    27. //释放
    28. free(ptr);
    29. ptr = NULL;
    30. return 0;
    31. }

    二,calloc函数:

    同样我们还是先来看一下这个函数的返回值和参数以及功能有哪些

    参数:num是开辟的字节大小,size是开辟的个数。

    返回值:void*类型,开辟内存成功也是返回首地址,失败返回NULL;

    与malloc不同的是,calloc会对开辟的内存进行一个初始化的操作,初始化全为0。

     用例:

    1. int main()
    2. {
    3. //开辟4个字节的内存5个
    4. int* ptr = (int*)calloc(5, 4);
    5. //int* ptr = (int*)calloc(5, sizeof(int));
    6. if (ptr == NULL)
    7. {
    8. strerror(errno);
    9. return 1;
    10. }
    11. for (int i = 0; i < 5; i++)
    12. {
    13. *(ptr + i) = i;
    14. }
    15. for (int i = 0; i < 5; i++)
    16. {
    17. printf("%d ", *(ptr + i));
    18. }
    19. //释放
    20. free(ptr);
    21. ptr = NULL;
    22. return 0;
    23. }

     calloc相比于malloc更加灵活了一些!,区别就是calloc会对内存初始化为0,而malloc不会。

    三,realloc函数:

    reaclloc函数可以更改指定内存块的大小

     参数:ptr指向的内存块,size无符号整形

    返回值:更改成功返回有两种可能性:

                    1,返回值原有的地址,2,返回新的地址

    为什么会有这两种情况呢?原因是,当更改的内存和原有的内存是连续的话,更改完之后内存快的地址没有发生改变,返回的就是原地址。如下图:(减小原内存快空间的话返回的肯定是原地址)

    并不是所有时刻更改的内存都是连续的,那么当更改的内存并不连续的时候realloc会新开辟一块大的空间,并将原数据拷贝到新开辟的内存快中,并返回新的内存地址!并将原内存块释放掉(自动释放)如下图:

    注意,新分配出来的空间也是不进行初始化的!

    如果更改不成功的话,返回NULL;

     下面我们对第一例代码进行改造,让得能放下10个数据。

    1. #include
    2. #include
    3. #include
    4. int main()
    5. {
    6. int* ptr = (int*)malloc(20);
    7. if (ptr == NULL)
    8. {
    9. strerror(errno);
    10. return 1;
    11. }
    12. ptr = (int*)realloc(ptr, 40);
    13. for (int i = 0; i < 10; i++)
    14. {
    15. *(ptr + i) = i;
    16. }
    17. for (int i = 0; i < 10; i++)
    18. {
    19. printf("%d ", *(ptr + i));
    20. }
    21. //释放
    22. free(ptr);
    23. ptr = NULL;
    24. return 0;
    25. }

    运行结果:

  • 相关阅读:
    IB学生喜欢申请哪些英国院校?
    C#,入门教程——解决方案资源管理器,代码文件与文件夹的管理工具
    1.4 系统环境变量
    .NET Core 中插件式开发实现
    使用 DDPO 在 TRL 中微调 Stable Diffusion 模型
    【Spring】三周玩转Spring全家桶
    linux,windows命令行输出控制指令,带颜色的信息,多行刷新,进度条效果,golang
    数据结构学习笔记(Ⅶ):查找
    React native 近期Android 无法编译的问题解决
    【API要返回一棵树的结构】数据库表结构是平铺的数据,但是api要实现树状结构展示。api实现一棵树的结构,如何实现呢,递归?如何递归呢
  • 原文地址:https://blog.csdn.net/Javaxaiobai/article/details/127036935