• 简单的介绍一下:柔性数组


    对于柔性数组,其实这个是在如今的大学生书本上是很难能找到的!!原因在于:笔者现在就是大学生一枚!!但是在C语言的书本上没有涉及到柔性数组的部分!!经查略资料,我们可以找到:在如今的C语言中:C99规定:结构体中允许最后一个元素是未知大小的数组!这个未知大小的数组,就是柔性数组!!

    对于柔性数组的定义,可能还没有开始,到此时就已经结束了!!想必大家也是心存疑惑?毕竟柔性数组部分是大家很少设计的知识盲区!!

    下面笔者就在一个结构体里面定义一个柔性数组来带领大家分析一下:

    1. struct s
    2. {
    3. int n;
    4. float m;
    5. int arr[];//柔性数组
    6. };

    对于柔性数组的那个代码,我们也可以进行一下写法:

    1. struct s
    2. {
    3. int n;
    4. float m;
    5. int arr[0];//柔性数组
    6. };

    注意上面两个结构体变量中的柔性数组的区别!!在上面的结构体代码中,是两种柔性数组的写法!!

    对于柔性数组有以下几个特点:

    1. 结构体中的柔性数组成员前面至少有一个其他成员(结构体成员)
    2. sizeof返回的是这个结构体的大小,不包含柔性数组的大小!

    请看下列求结构体大小的代码:

    1. #include
    2. struct s
    3. {
    4. int n;
    5. float m;
    6. int arr[0];//柔性数组
    7. };
    8. int main()
    9. {
    10. printf("%d \n", sizeof(struct s));
    11. return 0;
    12. }

    笔者亲测,在VS2022的X86与X64的环境下,运行的结果都是一样的!!请各位老铁不用怀疑在32/64位机器下运行结果不一样的原因了!!

     上述代码的运行结果位:

     对于结构体的大小,不知道各位老铁还有没有印象??在此对于该结构体的大小,笔者就不再进行多讲述了!!如果稍微有点模糊,请欣赏笔者的文章:如何计算:结构体内存的大小(在结构体的考察中占据非常重要的地位)原文链接位:

    如何计算:结构体内存的大小(在结构体的考察中占据非常重要的地位)_念君思宁的博客-CSDN博客


    包含柔性数组成员的结构体,用malloc函数进行内存的动态分配,并且分配的内存应该大于结构体的大小,以便于适应柔性数组的预期大小

    用法为:

    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. struct s
    4. {
    5. int n;
    6. float m;
    7. int arr[0];//柔性数组
    8. };
    9. int main()
    10. {
    11. struct s* ps = (struct s*)malloc(sizeof(struct s) + 4*sizeof(int));
    12. if (ps == NULL)
    13. {
    14. return 1;
    15. }
    16. ps->n = 100;
    17. ps->m = 5.5f;
    18. int i = 0;
    19. printf("请输入柔性数组的成员:4个整型:\n");
    20. for (i = 0; i < 4; i++)
    21. {
    22. scanf("%d", &(ps->arr[i]));
    23. }
    24. printf("输出结构体变量:\n");
    25. printf("%d %f\n", ps->n, ps->m);
    26. for (i = 0; i < 4; i++)
    27. {
    28. printf("%d ", ps->arr[i]);
    29. }
    30. //释放
    31. free(ps);
    32. ps = NULL;
    33. return 0;
    34. }

    对于上述的代码:

     上述代码的运行结果为:

     但是,当我们向增加一些内存的话(malloc函数开辟的空间不够用),我们可以用realloc函数来扩增动态内存开辟的空间,即笔者的代码为:

    1. //realloc函数来扩增空间!!
    2. struct s* ptr = (struct s*)realloc(ps, sizeof(struct s) + 10 * sizeof(int));
    3. //扩增内存空间
    4. if (ptr == NULL)
    5. {
    6. return 1;
    7. }
    8. else
    9. {
    10. ps = ptr;
    11. }
    12. //进行使用!!

    将上面的代码,插入在free(ps)的前面就行了!!在此,笔者就不做过多的讲解了!

    通过上面的案列,我们可以看出来:柔性数组的:主要体现在:可以对开辟空间进行realloc,不用再改代码!


    对于上述的代码,我们还有另外一种写法:

    1. #include <stdio.h>
    2. #include <stdlib.h>
    3. struct s
    4. {
    5. int n;
    6. float m;
    7. int* arr;
    8. };
    9. int main()
    10. {
    11. struct s* ps = (struct s*)malloc(sizeof(struct s));
    12. if (ps == NULL)
    13. {
    14. return 1;
    15. }
    16. ps->n = 100;
    17. ps->m = 5.5f;
    18. int* ptr = (int*)malloc(4 * sizeof(int));
    19. if (ptr == NULL)
    20. {
    21. return 1;
    22. }
    23. else
    24. {
    25. ps->arr = ptr;
    26. }
    27. //使用
    28. printf("请输入柔性数组的成员:4个整型:\n");
    29. int i = 0;
    30. for (i = 0; i < 4; i++)
    31. {
    32. scanf("%d", &(ps->arr[i]));
    33. }
    34. //打印
    35. printf("输出结构体变量:\n");
    36. printf("%d %f\n", ps->n, ps->m);
    37. for (i = 0; i < 4; i++)
    38. {
    39. printf("%d ", ps->arr[i]);
    40. }
    41. //释放
    42. free(ps->arr);
    43. ps->arr = NULL;
    44. free(ps);
    45. ps = NULL;
    46. return 0;
    47. }

    代码的运行结果为:

     在结构体中:

    1. struct s
    2. {
    3. int n;
    4. float m;
    5. int* arr;
    6. };
    1. 结构体里包含指针,指针指向一片malloc函数开辟的空间!
    2. int* arr  将arr所指向的空间进行malloc

     

     经过上面的简单介绍柔性数组,想必大家也能看出来:柔性数组的优势了!!

    第一个好处是方便内存释放

    如果我们的代码是在一个给别人用的函数中,你在里面做了二次内存分配,并把整个结构体返回给 用户。用户调用free可以释放结构体,但是用户并不知道这个结构体内的成员也需要free,所以你 不能指望用户来发现这个事。所以,如果我们把结构体的内存以及其成员要的内存一次性分配好 了,并返回给用户一个结构体指针,用户做一次free就可以把所有的内存也给释放掉。

    第二个好处是:这样有利于访问速度.

    连续的内存有益于提高访问速度,也有益于减少内存碎片。(其实,我个人觉得也没多高了,反正 你跑不了要用做偏移量的加法来寻址)

  • 相关阅读:
    rust函数
    Linux fdformat命令教程:如何进行软盘的低级格式化(附案例详解和注意事项)
    初识进程状态
    (附源码)云南濒危动物知识问答系统的设计与实现 毕业设计 020833
    查找排序部分习题 242. 有效的字母异位词 74. 搜索二维矩阵 1. 两数之和 167.两数之和 II
    【PowerQuery】Excel的PowerQuery的复制
    周亚军 红宝书 案例 3 telnet远程管理协议
    如何用C/C++实现去除字符串头和尾指定的字符
    Spring Cloud Gateway实现限流
    web:[极客大挑战 2019]PHP
  • 原文地址:https://blog.csdn.net/weixin_64308540/article/details/127450369