C語言柔性數組講解

來源:互聯網
上載者:User

標籤:緩衝區   std   ack   流量   根據   main   語言   緩衝   10個   


#include<stdio.h>typedef struct _SoftArray{ int len; int array[];}SoftArray;int main(){ int len = 10; printf("The struct‘s size is %d\n",sizeof(SoftArray));}

 

 

 

 

 

我們可以看出,_SoftArray結構體的大小是4,顯然,在32位作業系統下一個int型變數大小剛好為4,也就說結構體中的數組沒有佔用記憶體。為什麼會沒有佔用內

存,我們平時用數組時不時都要明確指明數組大小的嗎?但這裡卻可以編譯通過呢?這就是我們常說的動態數組,也就是柔性數組。

先不要亂,讓我們再看一段代碼

#include<stdio.h>#include<malloc.h>typedef struct _SoftArray{    int len;    int array[];}SoftArray;int main(){    int len = 10;    SoftArray *p=(SoftArray*)malloc(sizeof(SoftArray) + sizeof(int)*len);    printf("After the malloc function the struct‘s size is %d\n”,sizeof(SoftArray));    return 0;}

 

是不是有點奇怪,為什麼申請了記憶體後結構體大小還是4呢?原因是動態申請的記憶體只是申請給數組拓展所用,從上個程式我們可以看出結構體的大小在建立時已經

確定了,array明確來說不算是結構體成員,只是掛羊頭賣狗肉而已。

下面我們來看看關於柔性數組的資料:

1、什麼是柔性數組?

柔性數組既數組大小待定的數組, C語言中結構體的最後一個元素可以是大小未知的數組,也就是所謂的0長度,所以我們可以用結構體來建立柔性數組。

2、柔性數組有什麼用途 ?

它的主要用途是為了滿足需要變長度的結構體,為瞭解決使用數組時記憶體的冗餘和數組的越界問題。

3、用法 :在一個結構體的最後 ,申明一個長度為空白的數組,就可以使得這個結構體是可變長的。對於編譯器來說,此時間長度度為0的數組並不佔用空間,因為數組名

本身不佔空間,它只是一個位移量, 數組名這個符號本身代 表了一個不可修改的地址常量 (注意:數組名永遠都不會是指標! ),但對於這個數組的大小,我們

可以進行動態分配,對於編譯器而言,數組名僅僅是一個符號,它不會佔用任何空間,它在結構體中,只是代表了一個位移量,代表一個不可修改的地址常量!

對於柔性數組的這個特點,很容易構造出變成結構體,如緩衝區,資料包等等:

typedef struct _SoftArray

{

    Int len;

    int array[];

}SoftArray;

這樣的變長數組常用於網路通訊中構造不定長資料包,不會浪費空間浪費網路流量,比如我要發送1024位元組的資料,如果用定長包,假設定長包的長度為2048,就

會浪費1024個位元組的空間,也會造成不必要的流量浪費。

 

4、舉個簡單是執行個體

#include<stdio.h>#include<malloc.h>typedef struct _SoftArray{int len;int array[];}SoftArray;int main(){    int len=10,i=0;        SoftArray *p=(SoftArray*)malloc(sizeof(SoftArray)+sizeof(int)*len);    p->len=len;        for(i=0;i<p->len;i++)   {        p->array[i]=i+1;    }    for(i=0;i<p->len;i++)   {          printf("%d\n",p->array[i]);    }    free(p);    return 0;}    

 

 

 

 

 

 

 

 

 

這代碼的作用是用柔性數組動態建立數組並輸出數組內容,這裡我就直接解釋解釋這兩句代碼

   SoftArray* p = (SoftArray*)malloc(sizeof(SoftArray) + sizeof(int) *10);

      p->len = 10;

   第一句,主要是根據你要定義的數組長度和資料類型以及柔性數組本身的大小來開闢一塊記憶體空間給柔性數組,第二個是定義len的長度,便於確定迴圈列印輸出

是迴圈的次數。

5、運行錯誤的解決

#include<stdio.h>#include<malloc.h>typedef struct _SoftArray{int len;int array[];}SoftArray;int main(){    int len=10,i=0;        SoftArray *p=(SoftArray*)malloc(sizeof(SoftArray)+sizeof(int)*len);    p->len=len;        for(i=0;i<11;i++)   {        p->array[i]=i+1;    }    for(i=0;i<11;i++)   {          printf("%d\n",p->array[i]);    }    free(p);    return 0;} 
所謂初生牛犢不怕死,我在寫柔性數組程式時,為了做了個大膽的嘗試,那就是我在上一個代碼中申請記憶體時申請了10,但賦值時我把大小寫了11,問題出現了, 話不多說,直接 

我當時不知道是什麼問題,我也蒙了~---~

但我又做出了一個偉大的決定,我把free(p)注釋掉了,結果11成功列印出來了。我當時真是One Face mengbi。

 

             後來才發現其實是因為在動態分配記憶體的時候往往分配的是一個連續的地址,這一點從可以使用*[a+3]來取值就能夠知道。 因此,在動態分配的時候,會在數組界限外加一個用來標識數組範圍的標誌,例如a數組,就會在array[-1]和array[11]有兩個標誌,如果我們在這兩個位置賦值,賦 值和調用時並不會出錯,而是在freed掉array申請的記憶體時出錯,錯誤的名稱就是“DAMAGE: before Normal block”和“DAMAGE: after Normal block”。一般是後者居 多。因此,當你遇見這個錯誤的時候,記得去檢查一下自己數組的賦值吧。

6、注意說明

在定義這個結構體的時候,模子的大小就C89不支援這種東西,C99把它作為一種特例加入了標準。

但是,C99所支援的是 incomplete type,而不是 zero array,形同 int item[0];這種形式是非法的,C99支援的形式是形同 int item[];只不過有些編譯器把 int item[0];作

為非標準擴充來支援,而且在C99發布之前已經有了這種非標準擴充了,C99發布之後,有些編譯器把兩者合而為一了。當然,上面既然用 malloc函數分配了記憶體,

肯定就需要用 free函數來釋放記憶體:free(p);這兩個函數是一對CP,就好像fopen()和fclose();記住不要亂拆CP,拆CP是有風險的哦。

 

最後再送大家一個代碼玩玩:

 1 #include<stdio.h> 2 #include<malloc.h> 3 typedef struct _SoftArray{ 4     int len; 5     int array[]; 6 }SoftArray; 7  8 //列印輸出斐波那契數列 9 void printfln(SoftArray *p,int len)10 {11     int i;12 13     for(i=0;i<len;i++)        //迴圈進行列印輸出    14     {15         printf("%d\n",p->array[i]);16     }17 }18 19 //動態產生斐波那契數列20 void create(int len)21 {22     int i;23     24     SoftArray * p=(SoftArray*)malloc(sizeof(SoftArray)+sizeof(int)*len);    //聲明結構體指標p,動態申請記憶體,大小為結構體大小+10個int型大小25 26     for(i=0;i<len;i++)        //迴圈進行數組賦值27     {28         if( i <= 1 )29         {30             p->array[i] = 1;31         }else if( i >= 2 )32         {33             p->array[i] = p->array[i-1] + p->array[i-2];34         }else 35         {36             printf("DAMAGE: before Normal block or after Normal block");37             return (-1);38         }39         40     }41     printfln(p,len);42 43     free(p);44 }45 46 //主函數47 int main()48 {49     int i=0;50     int len;51 52     printf("請輸入產生斐波那契數列的行數:");53     scanf("%d",&len);54 55     create(len);56 57     return 0;58 }

 

C語言柔性數組講解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.