1. 程式人生 > >c語言變長結構體

c語言變長結構體

     1.什麼是變長陣列

struct MyData 
{
    int nLen;
    char data[0];
};   
sizeof(MyData)=4;

可能有的編譯器不支援char data[0];需要用char data[1];代替,這樣上面結構體大小是sizeof(MyData)=8(位元組對齊);

在上結構中,data是一個數組名;但該陣列沒有元素;該陣列的真實地址緊隨結構體MyData之後,而這個地址就是結構體後面資料的地址(如果給這個結構體分配的內容大於這個結構體實際大小,後面多餘的部分就是這個data的內容),這種宣告方法可以巧妙的實現C語言裡的陣列擴充套件

如下下所示:

#include <iostream>
using namespace std;
struct MyData 
{
    int nLen;
    char data[0];			//如果這裡用char* data;代替呢?是一個指標佔用空間,而採用變長陣列不佔記憶體,陣列名只是一個符號
							//代表一個不可修改的地址常量
};

int main()
{
    int nLen = 10;
    char str[10] = "123456789";

    cout << "Size of MyData: " << sizeof(MyData) << endl;

    MyData *myData = (MyData*)malloc(sizeof(MyData) + 10);
    memcpy(myData->data,  str, 10);

    cout << "myData's Data is: " << myData->data << endl;

    free(myData);

    return 0;
}


//輸出:
Size of MyData: 4
myData's Data is: 123456789   
//由於陣列沒有元素,該陣列在該結構體中不分配佔用空間,所以sizeof(struct Mydata) = 4。 

實際用時採取這樣:
         struct MyData *p = (struct MyData *)malloc(sizeof(struct MyData )+strlen(str))

這樣就可以通過p->data 來操作這個str。

struct MyData1 
{
    int nLen;
    char data[0];//char data[1];有的編譯要求這樣寫

};

struct MyData2 
{
    int nLen;
    char*data;

};

對於上面兩個結構體有下面幾點說明:
1. MyData1  (char data[0])結構體佔用記憶體最小,Mydata2有個指標佔用4B
2.MyData1與前面結構體資料是連續的記憶體儲存空間,而MyData2下,新增加資料data是單獨開闢的空間;
3.釋放記憶體時,MyData1可以直接釋放,而MyData2需要先釋放指標指向記憶體,然後再釋放結構體資料部分否則會記憶體洩漏