ziKmouT
ziKmouT

Reputation: 205

Coding realloc in C : trying to change the size of the allocation first

I am trying to recode realloc in C and I have a problem regarding the man and the realloc function I did because it does not do exactly what the man of realloc says.

Here is my code:

void *ft_realloc(void *ptr, size_t len) {
    void *dup;

    dup = ft_memalloc(len);
    if (ptr) {
        if (dup)
            ft_memcpy(dup, ptr, len);
        ft_memdel(&ptr);
    }
    return (dup);
}

But the man says:

The realloc() function tries to change the size of the allocation pointed to by ptr to size, and returns ptr. If there is not enough room to enlarge the memory allocation pointed to by ptr, realloc() creates a new allocation, copies as much of the old data pointed to by ptr as will fit to the new allocation, frees the old allocation, and >returns a pointer to the allo-cated memory.

The thing is, I have no idea how to "try to change the size of the allocation pointed to by ptr" (optimally I would like to do int without doing a strlen but by sending the size of ptr as a parameter of my realloc function). This part is missing in my code. Could you please help me on that? On top of that, I don not see any try to "change the size [...] to by ptr" if this opensource link which is rather weird to me!

Upvotes: 1

Views: 915

Answers (3)

chqrlie
chqrlie

Reputation: 144923

You need an ft_memsize(ptr) function to get the allocated size in order to copy the smaller of that and len to the newly allocated block.

Without such a function, you could only handle these trivial cases:

  • ft_realloc(NULL, size);: return malloc(size).
  • ft_realloc(ptr, 0);: free(ptr); and return NULL.

For all other cases, you would just fail and return NULL.

If you have it, use this:

void *ft_realloc(void *ptr, size_t len) {
    void *dup = NULL;
    size_t size = ptr ? ft_memsize(ptr) : 0;

    if (len == size)
        return ptr;

    if (len)
        dup = ft_memalloc(len);

    if (ptr && dup) {
        ft_memcpy(dup, ptr, size < len ? size : len);
        ft_memdel(&ptr);
    }
    return dup;
}

If you implemented the ft_memalloc and friends yourself, you know the details of the heap management, you may try and patch the internal heap structures instead of allocating a new block. This is what the Standard means by tries to change the size of the allocation pointed to by ptr to size:

  • If reallocating to the same size, you can just return the same block.
  • If reallocating to a smaller size, you may be able to split the block and create a free block at the end of the newly shrunk block at ptr. If there is not enough space to split the block, either create a new smaller block or return the current ptr.
  • If reallocating to a larger size, and the next blocks in memory are free, you may be able to coalesce the current block at ptr with its neighbors and return the same pointer.

Upvotes: 1

Jason
Jason

Reputation: 3917

Normally heap implementations like dlmalloc, ptmalloc, jemalloc, tcmalloc, etc... maintain memory in groups of chunk sizes.

So, when a realloc call is made, if the requested size is larger/smaller than the chunk size boundaries, it allocates a new chunk, copies/frees the old chunk, and returns the new chunk. Otherwise, it can just return the chunk passed in which is significantly faster.

The wikipedia page has a little more information.

Upvotes: 0

Scott Hunter
Scott Hunter

Reputation: 49873

The memory management system keeps track of the sizes of the allocations; that is how it can tell if a call to realloc is trying to change the size (also how it can do things like free()). You would need to do the same.

Upvotes: 2

Related Questions