结构体指针内的指针变量成员的内存分配

时间:2022-06-19 19:49:06

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长的地址