Question

I would like to convert malloc() to calloc(). I am confused about using calloc() in this example because it takes 2 arguments while malloc() only one. So it's correct with mine:

(byteBuffer)calloc(sizeof(byteBufferStruct), len + 1));

The example:

typedef struct byte_buf {
    size_t  len;
    uint8_t  *bytes;
} byteBufferStruct, *byteBuffer;


byteBuffer mallocByteBuffer(size_t len)
{
    byteBuffer retval;
    if((retval = (byteBuffer) malloc(sizeof(byteBufferStruct) + len + 1)) == NULL) return NULL;
    retval->len = len;
    retval->bytes = (uint8_t *) (retval + 1) ; /* just past the byteBuffer in malloc'ed space */
    return retval;
}
Was it helpful?

Solution

First: Both malloc() and calloc() return void *, which in C means you should not cast the return value.

Comparing the signatures of the functions, we have:

  • void * malloc(size_t size);
  • void * calloc(size_t nmemb, size_t size);

Basically, the argument to malloc() is the product of the arguments to calloc().

You can convert by just setting one of them to 1:

void * malloc_to_calloc(size_t size)
{
   return calloc(1, size);
}

Since the nmemb (number of members) to calloc() doesn't affect the actual structure of the memory in any way, this is safe.

Now we can use this to implement your allocation function (for clarity):

byteBuffer mallocByteBuffer(size_t len)
{
  byteBuffer b = malloc_to_calloc(len + 1 + sizeof *b);
  if(b != NULL)
  {
    b->len = len;
    b->bytes = (uint8_t *) (b + 1);
  }
  return b;
}

Note that sizeof is not a function. Also note the glaring asymmetry of asterisks that you get when you typedef away the asterisk. I don't recommend ever doing that.

OTHER TIPS

Instead of doing

if((retval = (byteBuffer) malloc(sizeof(byteBufferStruct) + len + 1)) == NULL) return NULL;

do

if (NULL == (retval = calloc(1, sizeof(byteBufferStruct) + len + 1))) 
  return NULL;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top