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

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值