首页 文章

如何使用char *成员为结构分配内存

提问于
浏览
3

我的结构看起来像这样:

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);

这对我来说是有意义的,这似乎有效,但只是想检查 .

2 回答

  • 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

    是的,你必须执行两个内存分配步骤是正确的,第一个用于struct,第二个用于字符串 .

    除非这是一个内存空间非常宝贵的嵌入式系统,否则解决此问题的一种方法是确定最大字符串大小 . 是的,这确实会浪费内存,例如,如果您通常只有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并为指针分配预先分配的存储,然后执行存储分配簿记 . 除非必须这样做,否则不要这样做 .

相关问题