我的结构看起来像这样:
struct tlv_msg
{
uint8_t datatype; //type of data
/* data stored in a union */
union{
int32_t s32val; /* int */
int64_t s64val; /* long long */
uint32_t u32val; /* unsigned int */
uint64_t u64val; /* unsigned long long */
char* strval; /* string */
unsigned char* binval; /* any binary data */
};
uint32_t bytelen; /* no. bytes of union/data part */
};
此结构使用联合来保存一些不同的数据类型。我有一个alloc函数,它为堆上的struct分配内存。我是否认为如果我分配一个整数类型(即联合上面的前四种类型),我只需按如下方式分配:
tlv_msg* msg = malloc(sizeof(tlv_msg));
sizeof(tlv_msg)返回24.我假设这是足够的字节来保存union中的最大数据类型以及其他数据成员。 (不知道为什么24 - 有人可以解释吗?)。
但是如果要存储的数据类型是指针类型,例如char *,那么我还需要这样做:
msg->strval = (char*)malloc(sizeof(string_length+1);
这对我来说是有意义的,这似乎有效,但只是想检查一下。
答案 0 :(得分:5)
这是完全正确的。
那就是说,你可能想创建辅助函数,以帮助你处理这个问题。
例如:
tlv_msg * new_tlv_msg( void );
/* There, you need to free struct members, if applicable */
void delete_tlv_msg( tlv_msg * msg );
/* Here you may copy your string, allocating memory for it */
tlv_msg_set_strval( tlv_msg * msg, char * str );
实施可能是(基本的,当然)
tlv_msg * new_tlv_msg( void )
{
return calloc( sizeof( tlv_msg ), 1 );
}
void delete_tlv_msg( tlv_msg * msg )
{
if( msg->strval != NULL )
{
free( msg-strval );
}
free( msg );
}
tlv_msg_set_strval( tlv_msg * msg, char * str )
{
if( msg->strval != NULL )
{
free( msg-strval );
}
msg->strval = strdup( str );
}
答案 1 :(得分:1)
是的,你必须执行两个内存分配步骤是正确的,第一个是结构,第二个是字符串。
除非这是一个内存空间非常宝贵的嵌入式系统,否则解决此问题的一种方法是确定最大字符串大小。是的,这确实会浪费内存,例如,如果您通常只有10个字符或更少的字符串,并分配25个字符。
#define WORKING_BUF_LEN 1024
struct tlv_msg
{
uint8_t datatype; //type of data
/* data stored in a union */
union{
int32_t s32val; /* int */
int64_t s64val; /* long long */
uint32_t u32val; /* unsigned int */
uint64_t u64val; /* unsigned long long */
char strval[WORKING_BUF_LEN={0}; /* string */
unsigned char* binval; /* any binary data */
};
uint32_t bytelen; /* no. bytes of union/data part */
};
如果您计划拥有许多这些结构并因此有许多char *指针,您也可以进行自己的内存管理以避免碎片堆碎,但这需要大量工作。您将使用宏覆盖new并为指针分配预先分配的存储,然后执行存储分配簿记。除非你必须这样做,否则不要这样做。