c語言變長結構體
阿新 • • 發佈:2019-01-07
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需要先釋放指標指向記憶體,然後再釋放結構體資料部分否則會記憶體洩漏