C語言結構體數組指針的動態分配

目前有在開發一個linux的底層驅動,涉及到很多種Modbus設備。程序是通過解析json配置文件,來獲知到底是訪問的什麼設備。剛開始,由於485設備的種類並不是很多,而且主機的每個485口下掛的設備數目,也不是很多,因此採用了靜態結構體數組的方式來做設備屬性和數值的緩存(Shadow)。但是目前485種類是越來越多,而且規定每個485口下,最多可以掛64個設備,如果全部用靜態數組的形式,則夠主機的RAM喝一壺的。。

例如單是一種VRV外機的P板,一個485口最多可以掛64個P板,每個P板可以帶64臺內機,每臺內機,可能有十幾個屬性。假定是12個屬性(每個屬性佔2字節),12*2*64*64 = 98KB了。這種消耗太大了。

於是,我們換一種方法,就是採用動態分配的方式。當程序解析出具體的設備類型後,在通過malloc函數,動態申請一塊內存,供設備屬性和數值的緩存使用。代碼如下:

int main(void)
{
	void *pDevShadow; //剛開始並不知道是何種設備,因此使用void類型定義

	//.........
	//僞代碼,假如判斷出設備是JM_DEWPOINT1類型
	//申請64個設備的RAM空間
	pDevShadow = (STRUCT_JM_DEWPOINT1 *)malloc(sizeof(STRUCT_JM_DEWPOINT1[64]));
	//如果申請失敗,則返回或則進行錯誤處理
	if(pDevShadow == NULL)return 0;

	printf("p Addr 0x%X, p+1 Addr 0x%X, P+sizeof Addr 0x%X\r\n", pDevShadow, pDevShadow+1, pDevShadow+sizeof(STRUCT_JM_DEWPOINT1));
	printf("sizeof pDevShadow is %d bytes\r\n", sizeof(STRUCT_JM_DEWPOINT1[64]));
	
	//額外定義一個結構體指針,這樣比較好操作。
	STRUCT_JM_DEWPOINT1 *pDewpoint;
	pDewpoint = pDevShadow;
	printf("pDew Addr is 0x%X, pDev+1 Addr is 0x%X\r\n", pDewpoint, pDewpoint+1);
	pDewpoint->Version = 0x02;
	pDewpoint->PowerRecover = 1;
	
	free(pDevShadow);
	pDevShadow = NULL;
}

代碼裏,我加了一些測試,就是想看下,各個指針是否指向了正確的地址。我們來看一下。

p Addr 0x81008, p+1 Addr 0x81009, P+sizeof Addr 0x81038
sizeof pDevShadow is 3072 bytes
pDew Addr is 0x81008, pDev+1 Addr is 0x81038

這裏我們看到,pDevShadow, pDevShadow+1的地址,就相差一個字節,因此可以得出,當訪問完第一個結構體,想要訪問第二個結構體是,是不能使用p+1這種方式的,而是應該使用pDevShadow+sizeof(STRUCT_JM_DEWPOINT1)這個地址。

但是每次使用pDevShadow+sizeof(STRUCT_JM_DEWPOINT1)會顯得很繁瑣,因此額外定義一個相應設備的結構體指針,則就會顯得方便很多。結構體數組操作起來會很方便。。另外還有個好處就是,寫代碼的時候,自動補全的功能也能用起來。

PS:以上其實是C語言的一些基本語法問題。之所以寫這篇文章,是因爲今天白天,我不小心就是拿p+1當做是第二個結構體來操作了,然後就遇到了Linux直接跳Bus Error。參考了以下的文章後,我就猜是指針地址不對。。。於是回家再測試了下代碼,發現確實是地址不對。。

https://blog.csdn.net/cjsycyl/article/details/14000621

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章