1

I am reading the following function declaration.

static uint8_t prv_read(uint16_t instanceId,
                        int * numDataP, 
                        lwm2m_data_t ** dataArrayP,
                        lwm2m_object_t * objectP) 

The 3rd argument lwm2m_data_t ** dataArrayP is a pointer to a pointer to the following struct.

typedef struct _lwm2m_data_t lwm2m_data_t;

struct _lwm2m_data_t
{
    lwm2m_data_type_t type;
    uint16_t    id;
    union
    {
        bool        asBoolean;
        int64_t     asInteger;
        double      asFloat;
        struct
        {
            size_t    length;
            uint8_t * buffer;
        } asBuffer;
        struct
        {
            size_t         count;
            lwm2m_data_t * array;
        } asChildren;
        struct
        {
            uint16_t objectId;
            uint16_t objectInstanceId;
        } asObjLink;
    } value;
};

I don't have much experience with pointers to pointers and my question is - is there an obvious reason why the author used a ** here? Or why would you use one?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
artic sol
  • 349
  • 6
  • 18

1 Answers1

1

You use a pointer to type T when you need to add a level of indirection to an object of type T. When type T happens to be a pointer, you make a pointer to a pointer.

In your particular situation it appears that the function needs to return several things at once. A common idiom in C for functions providing several results is to pass pointers to results into the function, and let the function set them. Your function provides three results:

  • The number of items in dataArrayP, through numDataP,
  • An array of data, through dataArrayP, and
  • An lwm2m object, through objectP

All three results are returned by setting pointers inside the function. The second result happens to be a pointer, i.e. lwm2m_data_t *. In order to return a pointer by setting a pointer, a double-pointer must be passed:

int numData;
lwm2m_data_t *dataArray;
lwm2m_object_t object;
uint8_t status = prv_read(instanceId, &numDataP, &dataArray, &object);

Note: Another common use for double-pointers is defining jagged arrays.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523