柔性数组详解

目录

一、柔性数组的特点:​

二、使用sizeof计算包含柔性数组的结构体的大小

三、柔性数组的使用

代码1:

四、用结构体指针代替柔性数组

代码2:

五、柔性数组与结构体指针对比


•  在结构体中

•  最后一个成员

•  未知大小的数组

这就是柔性数组

也许你从来没有听说过柔性数组(flexible array)这个概念,但是它确实是存在的。​
C99 中,柔性数组是一种动态可变的数组,结构中的最后一个元素允许是未知大小的数组,这就叫做『柔性数组』成员。​

typedef struct st_type {
    int i; //至少一个其他成员。
    int a[0];//柔性数组成员
}type_a;

有些编译器会报错无法编译,可以改成如下形式:

typedef struct st_type
{
 int i;
 int a[];//柔性数组成员
}type_a;

一、柔性数组的特点:​

结构中的柔性数组成员前面必须至少一个其他成员。
• sizeof 返回的这种结构大小不包括柔性数组的内存。​
包含柔性数组成员的结构用malloc ()函数进行内存的动态分配,并且分配的内存应该大于结构的大小,以适应柔性数组的预期大小。

二、使用sizeof计算包含柔性数组的结构体的大小

其得出的结果不包含柔性数组的内存

struct St
{int n;int arr[0];//int *arr;
};int main()
{printf("%d\n", sizeof(struct St));//4return 0;
}

三、柔性数组的使用

包含柔性数组成员的结构体要用malloc函数来进行内存的动态分配,并且分配的内存应大于结构体的大小,以适应柔性数组的预期大小。这样柔性数组成员a,相当于获得了100个整型元素的连续空间。如下所示:

•int arr[];//定义一个柔性数组

struct St s = {0};  // 定义并初始化一个St结构体变量s,其中所有成员都被初始化为0。

• struct St* ps = (struct St*)malloc(sizeof(struct St) + 10 * sizeof(int)); // 为ps分配内存

if (ps == NULL)//防止malloc开辟空间失败,导致内存泄漏
    {
        perror("malloc");
        return 1;
    }

free(ps);
  ps = NULL;

//先释放数组的内存,然后将结构体的内存也释放掉,并将指针设置为NULL,避免野指针。 

• struct St* ptr = (struct St*)realloc(ps, sizeof(struct St) + 15 * sizeof(int));

//使用 realloc 函数将数组的大小从10扩展到15。

代码1:

struct St
{char c;int n;int arr[0];//int *arr;
};int main()
{struct St* ps = (struct St*)malloc(sizeof(struct St) + 10 * sizeof(int));if (ps == NULL){perror("malloc");return 1;}ps->c = 'w';ps->n = 100;int i = 0;for (i = 0; i < 10; i++){ps->arr[i] = i;}//数组空间不够struct St* ptr = (struct St*)realloc(ps, sizeof(struct St) + 15 * sizeof(int));if (ptr != NULL){ps = ptr;}else {perror("malloc");return 1;}//...继续使用for (i = 10; i < 15; i++) {ps->arr[i] = i;}for (i = 10; i < 15; i++) {printf("%d ", ps->arr[i]);}printf("\n%d\n", ps->n);printf("%c\n", ps->c);//释放free(ps);ps = NULL;return 0;
}

四、用结构体指针代替柔性数组

上述的 type_a 结构也可以设计为下面的结构,也能完成同样的效果。

int *arr; //一个整型指针,可以用来动态分配数组。

if (ps == NULL)//防止malloc开辟空间失败,ps为空,导致内存泄漏
    {
        
perror("malloc");//报错一
        return 1;
    }


 ps->arr = (int*)malloc(10 * sizeof(int));
if (ps->arr == NULL)//防止malloc开辟空间失败,arr为空,导致内存泄漏
    {
        perror("malloc-2");//报错2
        return 1;
    }

代码2:

struct St
{char c;int n;//int arr[0];int *arr;
};int main(){struct St s = {0};printf("%d\n", sizeof(struct St));struct St* ps = (struct St*)malloc(sizeof(struct St));if (ps == NULL){perror("malloc");return 1;}ps->c = 'w';ps->n = 100;ps->arr = (int*)malloc(10 * sizeof(int));if (ps->arr == NULL){perror("malloc-2");return 1;}//使用int i = 0;for (i = 0; i < 10; i++){ps->arr[i] = i;}//数组空间不够int* ptr = (int*)realloc(ps->arr, 15 * sizeof(int));if (ptr == NULL){perror("realloc");return 1;}else{ps->arr = ptr;}//使用for (i = 10; i < 15; i++){ps->arr[i] = i;}for (i = 0; i < 15; i++){printf("%d ", ps->arr[i]);}printf("\n%d\n", ps->n);printf("%c\n", ps->c);//释放free(ps->arr);ps->arr = NULL;free(ps);ps = NULL;return 0;
}

五、柔性数组与结构体指针对比

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


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

今天就先到这了!!!

看到这里了还不给博主扣个:
⛳️ 点赞☀️收藏 ⭐️ 关注!

你们的点赞就是博主更新最大的动力!
有问题可以评论或者私信呢秒回哦。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/258096.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

吴恩达《机器学习》12-1:优化目标

在机器学习的旅程中&#xff0c;我们已经接触了多种学习算法。在监督学习中&#xff0c;选择使用算法 A 还是算法 B 的重要性逐渐减弱&#xff0c;而更关键的是如何在应用这些算法时优化目标。这包括设计特征、选择正则化参数等因素&#xff0c;这些在不同水平的实践者之间可能…

代码随想录算法训练营第三十八天|完全背包,518. 零钱兑换 II ,377. 组合总和 Ⅳ

完全背包 例题&#xff1a;有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i]&#xff0c;得到的价值是value[i] 。每件物品都有无限个&#xff08;也就是可以放入背包多次&#xff09;&#xff0c;求解将哪些物品装入背包里物品价值总和最大。 区别&#x…

机器学习硬件十年:性能变迁与趋势

本文分析了机器学习硬件性能的最新趋势&#xff0c;重点关注不同GPU和加速器的计算性能、内存、互连带宽、性价比和能效等指标。这篇分析旨在提供关于ML硬件能力及其瓶颈的全面视图。本文作者来自调研机构Epoch&#xff0c;致力于研究AI发展轨迹与治理的关键问题和趋势。 &…

小红书蒲公英平台开通后,有哪些注意的地方,以及如何进行报价?

今天来给大家聊聊当小红书账号过1000粉后&#xff0c;开通蒲公英需要注意的事项。 蒲公英平台是小红书APP中的一个专为内容创作者设计的平台。它为品牌和创作者提供了一个完整的服务流程&#xff0c;包括内容的创作、推广、互动以及转换等多个方面。 2.蒲公英平台的主要功能 &…

第一启富金:新添澳大利亚(ASIC)牌照

第一启富金&#xff1a;澳大利亞證券及投資委員會&#xff08;ASIC&#xff09; GOLDWELL GLOBAL PTY LTD 是 WHOLESALE INVESTOR SERVICES PTY LTD&#xff08;CAR 編號 001304943&#xff09;的企業授權代表開發澳大利亞客戶&#xff0c;WHOLESALE INVESTOR SERVICES PTY LT…

前端学习系列之CSS

目录 CSS 简介 发展史 优势 基本语法 引用方式 内部样式 行内样式 外部样式 选择器 id选择器 class选择器 标签选择器 子代选择器 后代选择器 相邻兄弟选择器 后续兄弟选择器 交集选择器 并集选择器 通配符选择器 伪类选择器 属性选择器 CSS基本属性 优…

Java_LinkedList链表详解

目录 前言 ArrayList的缺陷 链表 链表的概念及结构 链表的种类 1.单向或双向 2.带头或不带头 3.循环或不循环 LinkedList的使用 什么是LinkedList LinkedList的使用 LinkedList的构造 LinkedList的其他常用方法介绍 LinkedList的遍历 ArrayList和LinkedList的…

深入了解Java 8日期时间新玩法之Year、YearMonth、MonthDay、DayOfWeek

推荐语 在这篇文章中&#xff0c;我们将深入探讨Java 8中Year、YearMonth、MonthDay和DayOfWeek类的功能和使用方法。这些类是在Java 8中引入的新的日期时间API的一部分&#xff0c;它们为我们提供了更灵活、更易用的日期和时间处理能力。 尽管这些类在Java 8中已经出现&…

跨境电商系统搭建 无货源系统对接API 反向代购系统

跨境电商系统是为国外的客户代购中国商品的系统&#xff0c;系统实现与国内电商API对接&#xff0c;客户可直接在系统中搜索国内电商平台的商品。查看演示网站 一级功能二级功能 标准版 高级版 企业版 企业旗舰版 大客户尊享版 标准版高级版企业版企业旗舰版大客户尊享版 前台主…

泽攸科技二维材料转移台的应用场景及优势

随着二维材料的广泛研究和各种潜在应用的开发&#xff0c;对于二维材料样品的精密操控与转移的需求日益增加。特别是一些新型二维材料的制备和器件集成制备中&#xff0c;需要在显微镜下对样品进行观察与定位&#xff0c;并能够在微米甚至纳米量级上精确移動和转移样品。 传统…

溯源取证-WEB流量分析-简单

话不多说直接干&#xff1a; 题干&#xff1a; 开发团队在公司的一个 Web 服务器上发现了异常文件&#xff0c;开发团队怀疑该服务器上存在潜在的恶意活动&#xff0c;网络团队准备了一个包含关键网络流量的 pcap 文件&#xff0c;供安全团队分析&#xff0c;而你的任务是分析…

数学建模-二氧化碳排放及时空分布测度

二氧化碳排放及时空分布测度 整体求解过程概述(摘要) 面临全球气候变化的巨大挑战&#xff0c;我国积极响应《巴黎协定》的号召&#xff0c;提出“2030年前碳达峰&#xff0c;2060 年前实现碳中和”的碳排放发展目标&#xff0c;并将碳中和相关工作作为 2021 年的重点任务之一…