capi-designsoftware-designmemory-reallocation

Designing a resize function for a queue


I'm currently trying to design a public API for a queue data structure and resize function to change its size. My first intention was to do it in the following way:

typedef struct queue queue;

/**
 * Resizes a given queue.
 *
 * Changes the size of the queue passed as a parameter. 
 * The content of the resized queue prior to the lesser
 * of new and old sizes is left unchanged. 
 *
 * Returns:
 *  0 - on success
 * -1 - on error and the content of the original queue is left unchanged
 */
int queue_resize(queue * queue_ptr, size_t new_size);

The problem is I read the contract to realloc and it was the following:

The realloc function returns a pointer to the new object (which may have the same value as a pointer to the old object), or a null pointer if the new object could not be allocated.

Is it a common approach for reallocation functions to return a new object and reclaim the old one? So in such a case I should have redesigned the int queue_resize(queue *queue_ptr, size_t); to make queue * queue_resize(queue *queue_ptr, size_t); with the corresponding contract changes.


Solution

  • realloc must be able to move the allocated space to a different address for it to be able to work. Imagine the memory directly after the currently allocated memory was already in use. Without relocation you could not create a contiguous sequence.

    Typically your queue will look something like this

    typedef struct queue {
      some_type* data_member;
      size_t size;
      size_t capacity;
      // .. perhaps more
    } queue;
    

    So when you have a queue_resize function you can just pass a queue* and the new size. What you pass to realloc is not the queue* but its data_member. Since you already have a pointer to the queue object, you can just update the pointer of data_member if realloc chooses to change it.

    In this case returning a new queue* object is not necessary, because the memory footprint of queue never changes. Nor do you have to pass a queue** or anything of the sort.