要构建嵌套的TLV元素(例如,6F1A840E315041592E5359532E4444463031A5088801025F2D02656E),我使用以下数据结构:
typedef struct Element
{
int16_t nTag; // Tells you if pValue points to a primitive value or constructed one
uint16_t nLength;
void *pValue; // Could be either unsigned char* or TlvElement*
} TlvElement;
如何实现正确释放嵌套TLV元素使用的内存的函数?
// Let's build TLV data: 6F04A5020000
TlvElement *pTlvElement = (TlvElement*)malloc(sizeof(TlvElement));
pTlvElement->nTag = 0x6F;
pTlvElement->nLength = 4;
pTlvElement->pValue = malloc(sizeof(TlvElement)); // pValue points to another TLV element
TlvElement *pTlvElementChild = (TlvElement*)pTlvElement->pValue;
pTlvElementChild->nTag = 0xA5;
pTlvElementChild->nLength = 2;
pTlvElementChild->pValue = malloc(2 * sizeof(unsigned char)); // pValue points to a byte array
memset(pTlvElementChild->pValue, 0, 2);
Deallocate(pTlvElement);
//free(pTlvElementChild->pValue);
//free(pTlvElement->pValue);
//free(pTlvElement);
答案 0 :(得分:0)
您只需按照注释行中的顺序解除分配:
free((TlvElement *)(pTlvElement->pValue)->pValue);
free(pTlvElement->pValue);
free(pTlvElement);
函数free(void *)
需要void *
,因此编译器不会抱怨。您需要的唯一演员是访问子元素的字段pValue
。
请注意:除非tag
已经标记了这一点,否则您可以考虑添加一个元素确实包含子元素的地方。
假设->nTag
字段的值可用于此,您可以递归地释放子元素:
void Deallocate(TlvElement *e)
{
if (e->nTag == 0x6f)
Deallocate((TlvElement *)e->pValue);
else
free(e->pValue)
free(e);
}
但是,您可能希望采取预防措施来防止无休止的递归。