AJ.
AJ.

Reputation: 2569

how to malloc for this structure

typedef struct testMsg_ {
    unsigned char opCode;
    unsigned int  Count;
    char    *macsStrList[MAC_ADDR_STR_LEN];
} testMsg_t;

Number of elements in macsStrList is m_Count.

I know following is not correct:

testMsg_t *pInput = (testMsg_t *) malloc(sizeof(testMsg_t) );

Upvotes: 0

Views: 185

Answers (3)

Soren
Soren

Reputation: 14708

This is correct, given the structure you have done

testMsg_t *pInput = (testMsg_t *) malloc(sizeof(testMsg_t) );

However you are probably confused to the meaning of *arr[dimension] -- which is an array length dimension of pointers to chars -- reading between the lines,

MAC_ADDR_STR_LEN

Is probably ment to the legth of the string representation of a mac address (say <20 bytes?)

However your struct gives you 20 char pointers, and the character pointers still have to be initializaed to point to valid memory.

testMsg_t *pInput = (testMsg_t *) malloc(sizeof(testMsg_t) );
pInput->macsStrList[0] = (char *) malloc( MAC_ADDR_STR_LEN+1 );
pInput->macsStrList[1] = (char *) malloc( MAC_ADDR_STR_LEN+1 );
pInput->macsStrList[2] = (char *) malloc( MAC_ADDR_STR_LEN+1 );
...

or redefine your struct to

typedef struct testMsg_ {
    unsigned char opCode;
    unsigned int  Count;
    char    macsStrList[NUMBER_OF_MAC_ADDRESSES][MAC_ADDR_STR_LEN];
} testMsg_t;

To avoid having to deal with multiple number of allocations.

ADDITION;

As per comments, given that the number of mac addresses are dynamically determined, you could also define the struct as;

typedef struct testMsg_ {
        unsigned char opCode;
        unsigned int  Count;
        char    macsStrList[1][MAC_ADDR_STR_LEN];
    } testMsg_t;

and then allocate it using

testMsg_t *pInput = (testMsg_t *) malloc(sizeof(testMsg_t) + (countOfMacsAddresses * MAC_ADDR_STR_LEN) );

That would have the added over a solution with pointers of that you could use realloc to resize the array dynamically if you needed to do that as well.....

Upvotes: 3

Useless
Useless

Reputation: 67802

I think what you're looking for is maybe (ok, Soren got in first, but I'll show a way to allocate a single contiguous chunk):

/* assuming we only need macStrList[0] ... [Count-1] */
struct testMsg
{
    unsigned char opCode;
    unsigned int  Count;
    char *macsStrList[];
};

struct testMsg *allocate_testMsg(int count)
{
    char *string_storage;
    struct testMsg *msg;

    size_t size = sizeof(struct testMsg)   /* base object */
                + (count * sizeof(char *)) /* char* array */
                + (count * (MAC_ADDR_STR_LEN+1)) /* char storage */
                ;

    msg = malloc(size);
    msg->Count = count;
    string_storage = (char *)&(msg->macStrList[count]);

    /* note msg->macStrList points to UNINITIALIZED but allocated storage.
       it might be sensible to zero-fill string_storage, depending on how you'll
       initialize it
    */
    for (count=0; count < msg->Count;
         ++count, string_storage += (MAC_ADDR_STR_LEN+1))
    {
        msg->macStrList[count] = string_storage;
    }

    return msg;
}

Upvotes: 1

lindelof
lindelof

Reputation: 35250

Of course it is. You allocate a pointer to a testMsg_t which is an alias for struct testMsg_. However you need to initialize this object yourself.

(And you don't need to cast the allocated pointer in C).

Upvotes: 0

Related Questions