【C語言】深入理解柔性數組:特點、使用與優勢分析

C語言學習

柔性數組
友情鏈接:C語言專欄


文章目錄

  • C語言學習
  • 前言:
  • 柔性數組
  • 一、柔性數組的特點
  • 二、柔性數組的使用
  • 三、柔性數組的優勢
  • 總結
  • 附錄
    • 上文鏈接
    • 專欄


前言:

在有結構體和動態內存分配的知識后,今天咱們來說說柔性數組吧!!!


柔性數組

C99 中,結構中的最后?個元素允許是未知大小的數組,這就叫做柔性數組成員。
例如:

struct S
{int i;int a[0];//柔性數組成員
};

有些編譯器會報錯?法編譯可以改成:

struct S
{int i;int a[];//柔性數組成員
};

一、柔性數組的特點

  1. 結構中的柔性數組成員前面必須至少一個其他成員。
  2. sizeof 返回的這種結構大小不包括柔性數組的內存。
  3. 包含柔性數組成員的結構用malloc ()函數進行內存的動態分配,并且分配的內存應該大于結構的大小,以適應柔性數組的預期大小。

示例:

struct S
{int i;int a[];//柔性數組成員
};
int main()
{printf("%d\n", sizeof(struct S));//輸出的是4return 0;
}

輸出:
在這里插入圖片描述

二、柔性數組的使用

//代碼1
#include<stdio.h>
#include<stdlib.h>
struct S
{int i;int a[];//柔性數組成員
};
int main()
{struct S* ps = (struct S*)malloc(sizeof(struct S) + 5 * sizeof(int));//動態開辟內存:4+20個字節//4個字節為i,20個字節為數組if (ps == NULL)//判斷是否開辟成功{perror("malloc failed");exit(EXIT_FAILURE);  }//使用:ps->i = 100;for (int i = 0; i < 5; i++){ps->a[i] = i;}//增加空間reallocstruct S* tmp = (struct S*)realloc(ps, sizeof(struct S) + 10 * sizeof(int)); //給數組增加20個字節(5個元素)if (tmp == NULL)//判斷是否開辟成功{perror("malloc failed");exit(EXIT_FAILURE);}ps = tmp;//繼續由ps管理這塊內存;tmp = NULL;//使用//……//釋放free(ps);ps = NULL;return 0;
}

三、柔性數組的優勢

上述的結構也可以設計為別的結構,也能完成同樣的效果。

//代碼2
#include<stdio.h>
#include<stdlib.h>
struct S
{int i;int* a;//通過指針指向一塊空間,實現與柔性數組相同的效果
};
int main()
{struct S* ps = (struct S*)malloc(sizeof(struct S));//動態開辟內存一個struct S大小的空間if (ps == NULL)//判斷是否開辟成功{perror("malloc failed");exit(EXIT_FAILURE);}ps->i = 100;ps->a = (int*)malloc(5 * sizeof(int)); //動態開辟內存5個int大小的空間,并將起始地址給aif (ps->a == NULL)//判斷是否開辟成功{perror("malloc failed");exit(EXIT_FAILURE);}//使用for (int i = 0; i < 5; i++){ps->a[i] = i;}//增加空間reallocint* tmp = (int*)realloc(ps->a, sizeof(10 * sizeof(int)));//給ps->a指向的空間增加20個字節(5個元素)if (tmp == NULL)//判斷是否開辟成功{perror("malloc failed");exit(EXIT_FAILURE);}ps->a  = tmp;tmp = NULL;//使用//……//釋放//注意先后順序free(ps->a );ps->a  = NULL;free(ps);ps = NULL;return 0;
}

上述代碼1和代碼2可以完成同樣的功能,但是代碼1的實現有兩個好處:
第一個好處是:方便內存釋放

咱們上面發現,代碼2我們會釋放兩次內存。有如果我們的代碼是在?個給別?用的函數中,你在里面做了二次內存分配,并把整個結構體返回給用戶。用戶調用free可以釋放結構體,但是用戶并不知道這個結構體內的成員也需要free,所以你不能指望用戶來發現這個事。所以,如果我們把結構體的內存以及其成員要的內存?次性分配好了,并返回給用戶?個結構體指針,用戶做?次free就可以把所有的內存也給釋放掉。

第二個好處是:這樣有利于訪問速度

連續的內存有益于提高訪問速度,也有益于減少內存碎片。圖示:
在這里插入圖片描述


總結

柔性數組是C99標準引入的重要特性,它允許在結構體的末尾定義一個長度可變的數組。通過結合動態內存管理,柔性數組能夠高效地處理不確定大小的數據集合,是C程序員進階必備技能之一。

附錄

上文鏈接

《動態內存分配避坑指南:六大易錯點解析與經典筆試題實戰》

專欄

C語言專欄

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/914992.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/914992.shtml
英文地址,請注明出處:http://en.pswp.cn/news/914992.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

RV126平臺NFS網絡啟動終極復盤報告

1. 初始目標與環境目標: 將RV1126開發板的啟動方式&#xff0c;由從eMMC內部存儲掛載根文件系統&#xff08;rootfs&#xff09;&#xff0c;切換為通過網絡掛載位于NFS服務器上的根文件系統。動機: 提升開發調試效率&#xff0c;實現代碼修改后僅需重啟即可驗證&#xff0c;免…

一臺顯示器上如何快速切換兩臺電腦主機?

我注意到很多人會遇到一個常見的情況&#xff1a;他們有兩臺電腦&#xff0c;一臺舊的用來處理基本的辦公任務&#xff0c;另一臺新的用來玩游戲。新手通常會用 DP端口連接第一臺電腦的顯示器&#xff0c;用 HDMI 連接第二臺電腦。當他們想在兩臺電腦之間切換時&#xff0c;經常…

抗輻照與國產替代:ASM1042在衛星光纖放大器(EDFA)中的應用探索

摘要&#xff1a;本文以國科安芯推出的ASM1042芯片為例&#xff0c;通過分析ASM1042的抗輻照性能、高速數據傳輸能力、可靠性以及國產化優勢&#xff0c;結合EDFA系統的需求特點&#xff0c;深入探討了其在商業衛星光纖放大器&#xff08;EDFA&#xff09;項目中的應用潛力。AS…

鴻蒙ArkUI:聲明式開發,高效構建全場景體驗

目錄 導言&#xff1a;開啟鴻蒙應用開發的新范式 ArkUI框架概覽 - 鴻蒙UI的靈魂 深入核心 - 聲明式UI開發范式 命令式 vs 聲明式&#xff1a;范式革命 ArkUI如何實現聲明式&#xff1f; 創建內置組件 創建自定義組件 自定義組件的基本結構 ArkUI框架的核心特性與優勢 …

數據查找 二叉查找樹

查找一般分為有序查找和無序查找&#xff0c;這邊在講有序查找例二分查找二分查找就是在有序數組中&#xff0c;通過mid(lowhigh)/2來判定中間值&#xff0c;將中間值與待查找的值進行比較&#xff0c;如果待查找的值大于中間值&#xff0c;那么就將范圍縮小&#xff0c;查找右…

幾款開源的安全監控與防御工具分享

安全監控與防御工具概述 在現代網絡安全架構中,合理選擇和部署一系列的安全監控、檢測、響應工具至關重要。下面我們將介紹一些常見的安全工具,包括 Elkeid、Wazuh、Caldera、ELK、Snort、Suricata、OpenHFW、OSSEC、GScan 和 Sysom,并詳細介紹它們的下載鏈接、用處、使用方…

Elasticsearch:ES|QL 改進的時間線

作者&#xff1a;來自 Elastic Toms Mura 讓我們回顧一下 ES|QL 的歷史和它的改進。 更多閱讀&#xff0c;Elasticsearch&#xff1a;ES|QL 查詢展示。 Elasticsearch 配備了眾多新功能&#xff0c;幫助你為自己的用例構建最佳搜索方案。查看我們的示例筆記本了解更多內容&…

Linux | Bash 子字符串提取

注&#xff1a;本文為 “ Bash 子字符串提取” 相關合輯。 英文引文&#xff0c;機翻未校。 如有內容異常&#xff0c;請看原文。 How to Extract Bash Substring? [5 methods] 如何提取 Bash 子字符串&#xff1f;[5 種方法] 2024-04-28 00:00:00 In Bash, a substring is…

Vue2 前端開發 - vue-quill-editor 富文本編輯器(編輯器基礎案例、編輯器配置參數解讀、編輯器事件)

一、vue-quill-editor 1、vue-quill-editor 概述vue-quill-editor 是一個基于 Quill 富文本編輯器的 Vue 組件vue-quill-editor 在 Vue 2 項目中可以很方便地集成與使用2、vue-quill-editor 安裝 執行如下指令&#xff0c;安裝 vue-quill-editor npm install vue-quill-editor …

斷網情況下,網線直連 Windows 筆記本 和Ubuntu 服務器

在斷網情況下&#xff0c;通過網線直連 Windows 筆記本 和 Ubuntu 服務器&#xff0c;并使用 VSCode 訪問服務器及 Docker 容器 的步驟如下&#xff1a;1. 物理連接&#xff08;網線直連&#xff09; 1.1 使用網線連接 用 網線&#xff08;Cat5e 或更高&#xff09; 連接 Windo…

消息隊列總結

為什么需要消息隊列&#xff1f; 隨著互聯網快速發展&#xff0c;業務規模不斷擴張&#xff0c;技術架構從單體演進到微服務&#xff0c;服務間調用復雜、流量激增。為了解耦服務、合理利用資源、緩沖流量高峰&#xff0c;「消息隊列」應運而生&#xff0c;常用于異步處理、服務…

C#引用轉換核心原理:類型視角切換

&#x1f50d; C#引用轉換核心原理&#xff1a;類型視角切換 引用類型由內存指針和類型標記組成&#xff08;如圖1&#xff09;。引用轉換不改變內存地址&#xff0c;僅改變編譯器識別對象的“視角”&#xff1a; B myVar1 new B(); // 實際B類型對象 A myVar2 (A)myV…

重要發布丨MaxKB V2正式發布,助力用戶快速構建企業級智能體

2025年7月18日&#xff0c;MaxKB V2版本正式發布。MaxKB是一個強大易用的企業級智能體平臺&#xff0c;致力于解決企業AI落地所面臨的技術門檻高、部署成本高、迭代周期長等問題&#xff0c;讓企業用戶落地AI更簡單。 秉承“開箱即用&#xff0c;伴隨成長”的設計理念&#xff…

大語言模型任務分解與匯總:從認知瓶頸到系統化解決方案

一、緣起&#xff1a;為什么大模型需要"分而治之" 1.1 從一個真實場景說起 設想這樣一個場景&#xff1a;你要求GPT-4幫你完成一份包含市場調研、競品分析、財務預測和戰略規劃的商業計劃書。即使是最先進的大模型&#xff0c;面對這樣的復雜任務也會"力不從心&…

Spring核心注解@RequestMapping詳解

RequestMapping 是 Spring Framework 中一個核心注解&#xff0c;用于在 Spring MVC&#xff08;或 Spring WebFlux&#xff09;中將 HTTP 請求映射到特定的處理器&#xff08;Controller 中的方法&#xff09;或處理器類。它告訴 Spring 框架&#xff1a;當一個匹配特定條件的…

OSPF路由協議的協商過程

OSPF的知識點非常多&#xff0c;協議過程也是一個不大不小的知識點&#xff0c;今天就簡單的說一下&#xff0c;OSPF是如何進行協商的。OSPF&#xff08;Open Shortest Path First&#xff09;協議是一種用于路由選擇的動態鏈路狀態協議&#xff0c;是大型網絡普遍使用的動態路…

MySql:索引,結構

文章目錄注意事項結構注意事項 主鍵字段在建表時&#xff0c;會自動創建主鍵索引添加唯一約束時&#xff0c;數據庫實際上會添加唯一索引。 解釋&#xff1a; 增&#xff1a;創建&#xff1a; create [unique] index 索引名 on 表名 (字段名……)&#xff1b;-- 舉例 :給tb…

ts學習2

JavaScript 中的每個值都有一組行為&#xff0c;您可以通過運行不同的操作來觀察這些行為。這聽起來很抽象&#xff0c;但作為一個簡單的例子&#xff0c;考慮我們可能在名為 message 的變量上運行的一些操作。 // Accessing the property toLowerCase // on message and then…

k8s環境使用Operator部署Seaweedfs集群(下)

作者&#xff1a;閆乾苓 文章目錄4.4.3 部署seaweedfs集群4.4.4 驗證集群運行狀態4.4.5 測試集群功能4.4.3 部署seaweedfs集群 集群Yaml示例 apiVersion: seaweed.seaweedfs.com/v1 kind: Seaweed metadata:name: seaweed1namespace: default spec:image: chrislusf/seaweedf…

【橘子分布式】gRPC(理論篇)

一、簡介 我們在前面學習了thrift rpc的知識&#xff0c;我們從其中接觸到了IDL&#xff0c;編解碼協議&#xff0c;服務的遠程調用(調用遠程服務就像在在本地調用一樣)等各種概念。 其實我個人對thrift的使用并不多&#xff0c;我更多的是使用今天我們要提到的一個RPC框架稱之…