zclReportCmd_t *reportCmd;
typedef struct { uint8 numAttr; // number of reports in the list zclReport_t attrList[]; // attribute report list } zclReportCmd_t;
typedef struct { uint16 attrID; // atrribute ID uint8 dataType; // attribute data type uint8 *attrData; // this structure is allocated, so the data is HERE // - the size depends on the data type of attrID } zclReport_t;
上述可知:
reportCmd为一结构体指针!该结构体内的attrList成员也是一结构体,attrList结构体有attrData指针成员!
像上述这种指针结构体嵌套有指针的,或是但凡有指针的内存分配,都必须为每个指针变量单独分配内存空间!
笼统的分配内存空间是错误的!
原因是:
一般的内存分配都是连续性的分配块内存的,指针变量存的是将要跳转的空间地址,没有把开辟的地址赋给嵌套在内层的指针变量!这样跳转到的地址并不一定就在刚分配开辟的连续地址内,只有将开辟的内存地址写在指针变量里,才能让指针跳到指定的开辟的内存空间!
上例中错误的笼统分配就是
reportCmd = (zclReportCmd_t *)osal_msg_allocate(sizeof(zclReportCmd_t)+sizeof(zclReport_t)+ len);
把attrData指针要指向的空间和reportCmd指向的空间分在一块了,开辟出的首地址赋给了reportCmd,reportCmd根据自己的值就可以正确的跳到开辟给自己的内存!但是没有给attrData变量赋属于他的开辟的地址,他根据自己原先随机值跳就不一定跳到刚开辟的内存地址!
正确的做法:
reportCmd = (zclReportCmd_t *)osal_msg_allocate(sizeof(zclReportCmd_t)+sizeof(zclReport_t));//+ len);
reportCmd->attrList[0].attrData = (uint8*)osal_msg_allocate(len);
两个指针就用两次开辟内存!
reportCmd->attrList[0].attrData是report指针的成员,故它的内存地址是开辟reportCmd就开了,后面开的是它指向的地址,也就是len长的地址