結構體指標內的指標變數成員的記憶體分配
阿新 • • 發佈:2019-02-09
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長的地址