C 語言之柔性數組

一 歷史

在c99標準出來以前。若是要在某個結構體中使用字符串變時,爲了使字符串變量存儲地址能與結構體總體連在一塊兒,須要這樣實現數組

#include <stdio.h>
#include <malloc.h>
#include <string.h>

typedef struct pen
{
    int len;
    char *data;//字符串變量
}pen;

int main(int argc, char **argv)
{
    char str[] = "this is a string";//須要填入的字符串
    /*
      動態申請一個pen類型結構體變量,
      它的大小爲,pen類型的自己長度,
      再加上str(須要填入字符串的長度),再加1,
    */
    struct pen *p = (struct pen*)malloc(sizeof(pen) + strlen(str) + 1);
    p->data= NULL;
    //設置p的長度爲目標字符串的長度
    p->len = strlen(str);
    
    
    /*
      將目標字符串拷貝到結構體對應的位置
      此處爲何p+1以後指向的是pen結構體存儲空間後的位置,而不是隻加一呢?
      由於此處的p+1偏移的是p指向類型大小的偏移量,什麼意思呢?p指向的類型爲pen類型的結構體,
      而pen類型的結構體大小爲 len(4字節)加上 data(8個字節),因爲此處有內存對齊的狀況,
      因此實際上pen大小爲 4 + 8 + 4(這個4爲內存對齊的多餘空間,若是再增長一個int類型的變量,
      pen的大小仍是爲16)=16字節
      因此此處p+1向後偏移了16字節,經過下方地址打印能夠詳細看出
     */
    strcpy((char*)(p + 1), str);
    //int所佔字節數,不一樣機器不一樣。通常64位爲4字節
    printf("sizeof(int): %ld\n", sizeof(int));
    //上文已說明,16字節
    printf("sizeof(pen): %ld\n", sizeof(pen));
    //起始地址
    printf("start: %p\n\n", (char*)p);
    //上文已說明,偏移後的地址
    printf("(p+1) : %p\n", (char*)(p+1));
    //偏移後,對應的字符串
    printf("(char*)(p+1): %s\n\n", (char*)(p+1));
    //結構體變量data的地址
    printf("&(p->data): %p\n", &(p->data));
    //數據,null,此處爲空,故此變量已經被浪費。訪問對應字符串數據須要(char *)(p+1)
    printf("p->data: %s\n\n", p->data);
}

二 柔性數組

經過上文咱們能夠看到,data字段是一個被浪費的指針(8個字節)。而且咱們想取到結構體下的字符串變量時須要(char *)(p+1)寫這麼一串東西,既很差看,也容易出錯,那有沒有能夠直接用p->data取到字符串而且內存是連續的,並且又不浪費data字段呢, 柔性數組 就是用來幹這個的。flex

#include <stdio.h>
#include <malloc.h>
#include <string.h>

typedef struct pen
{
    int len;
    char data[];//柔性數組
}pen;

int main(int argc, char **argv)
{
    char str[] = "this is a new string";//須要填入的字符串
    struct pen *p = (struct pen*)malloc(sizeof(pen) + strlen(str) + 1);
    p->data= NULL;
    p->len = strlen(str);
   strcpy((char *)(p+1), str);
 printf("pen->data: %s\n", p->data);
}

C99使用不完整類型實現柔性數組成員,在C99 中,結構中的最後一個元素容許是未知大小的數組,這就叫作柔性數組(flexible array)成員(也叫伸縮性數組成員),但結構中的柔性數組成員前面必須至少一個其餘成員。柔性數組成員容許結構中包含一個大小可變的數組柔性數組成員只做爲一個符號地址存在,並且必須是結構體的最後一個成員,sizeof 返回的這種結構大小不包括柔性數組的內存 (此段話摘自:https://blog.csdn.net/ce123_z...this

相關文章
相關標籤/搜索