在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

嵌入式中零長度數(shù)組基本操作方法

嵌入式開發(fā)星球 ? 來源:嵌入式開發(fā)愛好者 ? 作者:嵌入式開發(fā)愛好者 ? 2024-05-11 08:49 ? 次閱讀

C語言零長度數(shù)組,聽起來可能有點(diǎn)奇怪,因?yàn)樗鼪]有分配內(nèi)存空間,無法存儲(chǔ)數(shù)據(jù)。但實(shí)際上,零長度數(shù)組在Linux內(nèi)核中隨處可見。

wKgaomY_FmCASuqKAACr-GPuQ2c182.png

零長度數(shù)組的定義

首先,我們要明白什么是零長度數(shù)組。簡單來說,零長度數(shù)組就是一個(gè)長度為0的數(shù)組,也就是說不包含任何元素的數(shù)組。零長度數(shù)組在C99標(biāo)準(zhǔn)中引入,并在C11中得到進(jìn)一步的支持。其定義很簡單,就是一個(gè)大小為0的數(shù)組。例如:

int a[0];

在Linux內(nèi)核中,零長度數(shù)組通常不會(huì)直接這樣使用,而是作為結(jié)構(gòu)體中最后一個(gè)元素,配合動(dòng)態(tài)內(nèi)存分配來使用。

零長度數(shù)組在Linux內(nèi)核中的應(yīng)用案例

在Linux內(nèi)核中,經(jīng)常可以看到零長度數(shù)組被用作結(jié)構(gòu)體末尾的占位符,以表示結(jié)構(gòu)體的可變長度部分。例如,一個(gè)表示網(wǎng)絡(luò)套接字的struct sockaddr結(jié)構(gòu)體可能如下所示:

struct sockaddr { sa_family_t sa_family; // 地址家族,如AF_INET, AF_UNIX等 char sa_data[14]; // 對(duì)于IPv4,這里實(shí)際上只有12字節(jié)被使用 };

在這個(gè)例子中,sa_data字段實(shí)際上是一個(gè)填充字段,用于容納不同地址家族的地址數(shù)據(jù)。由于地址家族可能不同,所需的數(shù)據(jù)長度也可能不同,因此這里使用了一個(gè)足夠大的固定長度數(shù)組。然而,如果使用零長度數(shù)組,代碼會(huì)更加清晰:

struct sockaddr { sa_family_t sa_family; // 地址家族 char sa_data[0]; // 可變長度部分,實(shí)際使用時(shí)會(huì)動(dòng)態(tài)分配 };

在實(shí)際應(yīng)用中,內(nèi)核代碼會(huì)結(jié)合動(dòng)態(tài)內(nèi)存分配來設(shè)置需要的的sa_data長度,并填充相關(guān)的數(shù)據(jù)。零長度數(shù)組可以與kmalloc、vmalloc等內(nèi)存分配函數(shù)結(jié)合使用,來實(shí)現(xiàn)這種動(dòng)態(tài)分配,所以有人也把零長度數(shù)組稱為柔性數(shù)組。

如何具體實(shí)現(xiàn)結(jié)構(gòu)體動(dòng)態(tài)內(nèi)存分配?

在Linux內(nèi)核或其他C語言編寫的底層系統(tǒng)中,零長度數(shù)組經(jīng)常被用作靈活的數(shù)據(jù)結(jié)構(gòu)的一部分,特別是在需要?jiǎng)討B(tài)增長或縮小的數(shù)組中。以下是一個(gè)簡單的示例,展示了如何在內(nèi)核編程中使用零長度數(shù)組來實(shí)現(xiàn)一個(gè)可變長度的整數(shù)數(shù)組:

#include // 包含printk等內(nèi)核函數(shù) #include // 包含kmalloc和kfree等內(nèi)存管理函數(shù) // 定義一個(gè)結(jié)構(gòu)體,用于表示可變長度的整數(shù)數(shù)組 struct variable_int_array { size_t length; // 數(shù)組當(dāng)前長度 int data[0]; // 零長度數(shù)組,實(shí)際數(shù)據(jù)存儲(chǔ)在這里 }; // 創(chuàng)建一個(gè)新的可變長度整數(shù)數(shù)組 struct variable_int_array *create_int_array(size_t initial_length) { // 分配內(nèi)存,包括結(jié)構(gòu)體本身和初始長度的整數(shù)數(shù)組 struct variable_int_array *array = kmalloc( sizeof(struct variable_int_array) + initial_length * sizeof(int), GFP_KERNEL ); if (!array) { // 內(nèi)存分配失敗 return NULL; } // 初始化數(shù)組長度 array->length = initial_length; // 返回新創(chuàng)建的數(shù)組 return array; } // 銷毀一個(gè)可變長度整數(shù)數(shù)組 void destroy_int_array(struct variable_int_array *array) { if (!array) { // 空指針檢查 return; } // 釋放內(nèi)存 kfree(array); } // 向數(shù)組中添加一個(gè)新的整數(shù) void add_int_to_array(struct variable_int_array **array_ptr, int value) { struct variable_int_array *array = *array_ptr; size_t new_length = array->length + 1; // 分配新的內(nèi)存塊,包含擴(kuò)展后的數(shù)組 array = kmalloc( sizeof(struct variable_int_array) + new_length * sizeof(int), GFP_KERNEL ); if (!array) { // 內(nèi)存分配失敗 printk(KERN_ERR "Failed to extend the integer array.n"); return; } // 復(fù)制舊數(shù)組的值到新數(shù)組 memcpy(array->data, (*array_ptr)->data, array->length * sizeof(int)); // 添加新值 array->data[new_length - 1] = value; // 更新數(shù)組長度 array->length = new_length; // 釋放舊數(shù)組 kfree(*array_ptr); // 更新指向數(shù)組的指針 *array_ptr = array; } // 打印數(shù)組內(nèi)容 void print_int_array(struct variable_int_array *array) { for (size_t i = 0; i < array-?>length; i++) { printk(KERN_INFO "%d ", array->data[i]); } printk(KERN_INFO "n"); } // 內(nèi)核模塊初始化函數(shù) static int __init my_module_init(void) { struct variable_int_array *my_array = create_int_array(2); if (!my_array) { // 處理錯(cuò)誤 return -ENOMEM; } // 添加一些值 add_int_to_array(&my_array, 10); add_int_to_array(&my_array, 20); // 打印數(shù)組 print_int_array(my_array); // 銷毀數(shù)組 destroy_int_array(my_array); return 0; } // 內(nèi)核模塊退出函數(shù) static void __exit my_module_exit(void) { // 清理工作(如果有的話) } // 注冊(cè)模塊初始化和退出函數(shù) module_init(my_module_init); module_exit(my_module_exit); // 定義模塊許可證 MODULE_LICENSE("GPL");

在這個(gè)例子中,忽略內(nèi)核模塊相關(guān)部分,重點(diǎn)看結(jié)構(gòu)體variable_int_array相關(guān)幾個(gè)函數(shù)。

我們定義了一個(gè)名為variable_int_array的結(jié)構(gòu)體,它包含一個(gè)length字段和一個(gè)零長度數(shù)組data。使用create_int_array函數(shù)來分配內(nèi)存并初始化這個(gè)結(jié)構(gòu)體,同時(shí)使用destroy_int_array函數(shù)來釋放內(nèi)存。add_int_to_array函數(shù)允許我們向數(shù)組中添加新的整數(shù),它會(huì)動(dòng)態(tài)地重新分配內(nèi)存以容納新增加的元素。最后,print_int_array函數(shù)用來打印輸出出結(jié)構(gòu)體中整數(shù)動(dòng)態(tài)數(shù)組成員值。

下面具體來看看重點(diǎn)代碼的實(shí)現(xiàn)。

create_int_array函數(shù)創(chuàng)建一個(gè)新的可變長度整數(shù)數(shù)組的結(jié)構(gòu)體variable_int_array,函數(shù)形參initial_length是要?jiǎng)?chuàng)建數(shù)組初始長度。第13行使用kmalloc動(dòng)態(tài)分配結(jié)構(gòu)體初始內(nèi)存空間,這里包括結(jié)構(gòu)體本身和初始長度為initial_length的整數(shù)數(shù)組空間。第24行就是把initial_length,也即是初始數(shù)據(jù)長度值存到結(jié)構(gòu)體length成員中,因?yàn)殚L度不是0了而是initial_length。

destroy_int_array就是調(diào)用kfree釋放上面創(chuàng)建的內(nèi)存空間,這個(gè)比較簡單。

重點(diǎn)看看add_int_to_array(struct variable_int_array **array_ptr, int value)函數(shù),這個(gè)函數(shù)就是將一個(gè)新的整數(shù)值動(dòng)態(tài)添加到數(shù)組中,這也是最麻煩的過程。

第一個(gè)形參是結(jié)構(gòu)體array_ptr,是個(gè)二級(jí)指針,指向舊的結(jié)構(gòu)體內(nèi)存首地址,注意這個(gè)指針變量后面新分配內(nèi)存空間地址要存入其中。第二個(gè)形參value是被添加的新的整數(shù)值。

第43行是將舊的結(jié)構(gòu)體首地址存到array指針中。

第44行new_length暫時(shí)保存數(shù)組長度。

第47行是分配新的內(nèi)存空間,并將首地址存入array變量,注意從此以后array指向新空間。因?yàn)閿?shù)組新加了一個(gè)整數(shù),所以空間變大,要重新分配,新分配的空間大小包括之前舊的結(jié)構(gòu)體長度和新添加的一個(gè)整數(shù)的空間大小。

第59行是將舊的數(shù)組數(shù)據(jù)拷貝到新的數(shù)組空間中。

第62行就是新的整數(shù)值添加到新數(shù)組空間最后一個(gè)位置,到此數(shù)組空間數(shù)據(jù)更新完成。

第66行更新結(jié)構(gòu)體的length成員為new_length,其實(shí)就是加了個(gè)1。

第69行,釋放之前舊結(jié)構(gòu)體的所有內(nèi)存,因?yàn)殚L度增加分配了新內(nèi)存了。

第72行就是將新空間地址賦給array_ptr指針變量,這是讓指向舊結(jié)構(gòu)體首地址的指針指向新的結(jié)構(gòu)體首地址了,到此就結(jié)束了。

總結(jié)

簡單來說,零長度數(shù)組就是一個(gè)長度為0的數(shù)組。但在編程中,它常常被用作一個(gè)占位符,或者作為一個(gè)結(jié)構(gòu)體的最后一個(gè)元素,這樣可以在結(jié)構(gòu)體中靈活地存儲(chǔ)更多的數(shù)據(jù)。

那么,零長度數(shù)組有什么價(jià)值和意義呢?

靈活性:零長度數(shù)組允許我們?cè)诓恢谰唧w需要多少存儲(chǔ)空間的情況下,先分配一個(gè)基本的結(jié)構(gòu)體。這樣,我們可以在后續(xù)的程序執(zhí)行中,根據(jù)需要?jiǎng)討B(tài)地添加數(shù)據(jù)到這個(gè)零長度數(shù)組中。這種靈活性對(duì)于處理可變大小的數(shù)據(jù)非常有用。

內(nèi)存效率:通過動(dòng)態(tài)地分配內(nèi)存給零長度數(shù)組,我們可以避免一開始就分配過多的內(nèi)存,這樣可以更加高效地利用內(nèi)存資源。只有當(dāng)我們確實(shí)需要額外的存儲(chǔ)空間時(shí),才會(huì)分配額外的內(nèi)存。

簡化代碼:在某些情況下,使用零長度數(shù)組可以簡化代碼結(jié)構(gòu)。比如,我們可以將一些相關(guān)的數(shù)據(jù)都放在一個(gè)結(jié)構(gòu)體中,而零長度數(shù)組可以作為這個(gè)結(jié)構(gòu)體的最后一個(gè)元素,用于存儲(chǔ)額外的數(shù)據(jù)。這樣,我們可以更方便地管理和操作這些數(shù)據(jù)。

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 嵌入式
    +關(guān)注

    關(guān)注

    5082

    文章

    19122

    瀏覽量

    305107
  • 內(nèi)核
    +關(guān)注

    關(guān)注

    3

    文章

    1372

    瀏覽量

    40288
  • Linux
    +關(guān)注

    關(guān)注

    87

    文章

    11304

    瀏覽量

    209458
  • 內(nèi)存
    +關(guān)注

    關(guān)注

    8

    文章

    3024

    瀏覽量

    74038
  • C語言
    +關(guān)注

    關(guān)注

    180

    文章

    7604

    瀏覽量

    136793
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    嵌入式系統(tǒng)串口通信幀的同步方法

    制下面介紹一下簡化的串口通信數(shù)據(jù)幀結(jié)構(gòu),以便分析說明嵌入式系統(tǒng)串口通信過程的幀同步方法。 假定串口發(fā)送的數(shù)據(jù)幀結(jié)構(gòu)為: 其中:包頭用于同步,一般是一個(gè)或多個(gè)ASCII字符,本文中假定數(shù)據(jù)幀同步頭有2
    發(fā)表于 10-09 19:17

    怎么才能在使用ss集線器時(shí)丟失零長度數(shù)據(jù)包?

    上的每次讀之前都有一個(gè)寫在端點(diǎn)0x01上的操作,它的長度是預(yù)先知道的。讀取端點(diǎn)0x82沒有可預(yù)測長度,因此FPGA每20毫秒生成一個(gè)零長度,以完成當(dāng)前事務(wù)并喚醒主機(jī)。下面是我在主機(jī)側(cè)啟
    發(fā)表于 10-18 10:45

    systemd定時(shí)器的基本操作方法

    定時(shí)器任務(wù)作為嵌入式系統(tǒng)中常見的應(yīng)用,systemd 定時(shí)器為用戶提供更多的可配置功能以及優(yōu)化選項(xiàng)。本文列舉了 systemd 定時(shí)器基本操作方法,以及和cron 對(duì)比,幫助用戶更快得使用。更多的技術(shù)細(xì)節(jié)和功能請(qǐng)參考下面的鏈接內(nèi)容。
    發(fā)表于 01-01 07:37

    如何配置嵌入式服務(wù)器

    嵌入式Web服務(wù)器每個(gè)Spring Boot Web應(yīng)用程序都包含一個(gè)嵌入式Web服務(wù)器。此功能會(huì)導(dǎo)致許多操作方法問題,包括如何更改嵌入式服務(wù)器以及如何配置
    發(fā)表于 10-27 08:35

    嵌入式操作系統(tǒng)Linux 的串口應(yīng)用編程

    針對(duì)嵌入式Linux操作系統(tǒng)的特點(diǎn),分析在該系統(tǒng)下串行通信口編程控制的方法,總結(jié)程序設(shè)計(jì)的步驟; 在嵌入式Linux 系統(tǒng)上, 編寫控制程序, 成功地實(shí)現(xiàn)
    發(fā)表于 05-14 14:34 ?28次下載

    汽車電子嵌入式操作系統(tǒng)

    汽車電子嵌入式操作系統(tǒng)
    發(fā)表于 10-30 16:07 ?9次下載
    汽車電子<b class='flag-5'>中</b><b class='flag-5'>嵌入式</b><b class='flag-5'>操作</b>系統(tǒng)

    關(guān)于 Java 數(shù)組的 12 個(gè)最佳方法

    下文加介紹的是stackoverflow關(guān)于數(shù)組方法的相關(guān)問題中,獲得最多票數(shù)的12個(gè)數(shù)組操作方法
    發(fā)表于 01-29 09:45 ?905次閱讀

    Java數(shù)組的基本操作方法整理

    本文主要介紹了Java數(shù)組的基本操作方法整理,是Java入門學(xué)習(xí)的基礎(chǔ)知識(shí)。數(shù)組是具有相同數(shù)據(jù)類型的一組數(shù)據(jù)的集合,Java支持多為數(shù)組
    發(fā)表于 01-29 10:15 ?1213次閱讀

    基于μC/OS嵌入式操作系統(tǒng)的嵌入式數(shù)據(jù)管理設(shè)計(jì)

    較高要求,只能應(yīng)用在比較高端的嵌入式系統(tǒng)。在低端的嵌入式系統(tǒng),傳統(tǒng)的數(shù)據(jù)管理方法是對(duì)數(shù)據(jù)存儲(chǔ)空間按順序編號(hào),數(shù)據(jù)存儲(chǔ)與刪除均根據(jù)編號(hào)順序
    發(fā)表于 10-09 16:24 ?1232次閱讀
    基于μC/OS<b class='flag-5'>嵌入式</b><b class='flag-5'>操作</b>系統(tǒng)的<b class='flag-5'>嵌入式</b>數(shù)據(jù)管理設(shè)計(jì)

    嵌入式操作系統(tǒng)

    2.2 實(shí)時(shí)操作系統(tǒng)的評(píng)價(jià)指標(biāo)三、基于Linux的嵌入式操作系統(tǒng)3.1 ARMLinux簡介3.2 uCLinux簡介四、嵌入式操作系統(tǒng)設(shè)計(jì)
    發(fā)表于 11-03 18:36 ?46次下載
    <b class='flag-5'>嵌入式</b><b class='flag-5'>操作</b>系統(tǒng)

    C語言開發(fā)可能會(huì)用到的GNU

    ? ? 為了方便使用,GNU C在標(biāo)準(zhǔn)C語言的基礎(chǔ)上進(jìn)行了部分方便開發(fā)的擴(kuò)展。 這里講解一些開發(fā)可能會(huì)用到的,或者使用頻率比較高的內(nèi)容。 零長度數(shù)組和變量長度數(shù)組 ? GNU C 允許使用
    的頭像 發(fā)表于 11-17 10:41 ?1651次閱讀

    0長度數(shù)組不占用存儲(chǔ)空間

    由于0長度數(shù)組是GNU C的擴(kuò)展,有一些巧妙編寫的詭異代碼,其執(zhí)行結(jié)果就是依賴于編譯器和優(yōu)化策略的實(shí)現(xiàn)的,我們來看看以下代碼。
    的頭像 發(fā)表于 09-28 15:18 ?774次閱讀
    0<b class='flag-5'>長度數(shù)組</b>不占用存儲(chǔ)空間

    什么是嵌入式操作系統(tǒng)?

    嵌入式操作系統(tǒng)通常在嵌入式系統(tǒng)工作。嵌入式系統(tǒng)是支持機(jī)器的計(jì)算機(jī)。它在更大的機(jī)器上執(zhí)行一項(xiàng)任務(wù)。示例包括汽車
    的頭像 發(fā)表于 12-23 15:33 ?7772次閱讀
    什么是<b class='flag-5'>嵌入式</b><b class='flag-5'>操作</b>系統(tǒng)?

    零長數(shù)組如何使用定長包定義數(shù)據(jù)緩沖區(qū)

    零長數(shù)組 請(qǐng)先思考以下問題: C語言中,數(shù)組長度是否可以為0? 如果要接收一個(gè)不定長數(shù)據(jù)包,你會(huì)如何定義數(shù)據(jù)緩沖區(qū)? 第一個(gè)問題 : 在標(biāo)準(zhǔn)C語言中,沒有長度為0的
    的頭像 發(fā)表于 09-27 14:58 ?688次閱讀

    嵌入式工控機(jī)如何使用?嵌入式工控機(jī)操作方法及注意事項(xiàng)

    嵌入式工控機(jī)作為現(xiàn)代工業(yè)自動(dòng)化和控制系統(tǒng)重要的硬件支持,廣泛應(yīng)用于生產(chǎn)線監(jiān)控、軌道交通、電力能源等多個(gè)領(lǐng)域。其穩(wěn)定性、可靠性以及適應(yīng)惡劣環(huán)境的能力,使其成為許多行業(yè)的首選。那么,嵌入式工控機(jī)究竟如何使用呢?高能計(jì)算機(jī)將詳細(xì)介紹
    的頭像 發(fā)表于 10-18 10:02 ?327次閱讀
    主站蜘蛛池模板: 日韩免费一级毛片| 国产一区国产二区国产三区| 亚洲国产成人久久精品影视| 亚洲人成网站色7799在线播放 | 狠狠色噜噜狠狠狠狠狠色综合久久 | 色妞网| 老师受年下高h男| 91麻豆麻豆| 四虎a级欧美在线观看| 日本中文在线三级在线播放| 欧美三级色| 国产裸体美女视频全黄| 夜夜夜爽爽爽久久久| 六月丁香综合网| 六月丁香激情网| 97人人揉人人捏人人添| 恐怖片大全恐怖片免费观看好看的恐怖片 | 女人张开腿等男人桶免费视频| 黄色网毛片| 五月天婷婷免费视频观看| 黄色视网站| 视频精品一区二区三区| 午夜精品久久久久蜜桃| 欧美freesex交| 免费看片免| 午夜湿| 四虎影业| 影院午夜| 黄色网址在线播放| 日本免费网站观看| 欧美黑粗特黄午夜大片| 亚洲国产网址| 色多多官网| 成人免费看黄页网址大全| 免费精品美女久久久久久久久| 在线中文字幕第一页| 免费人成黄页在线观看日本| 天天做天天添天天谢| 4455亚洲| 色婷婷综合网| 最新国产精品视频免费看|