# Strdup does not calls redefined malloc/free

**URL:** <https://forums.freertos.org/t/strdup-does-not-calls-redefined-malloc-free/14972>\
**Category:** Kernel\
**Created:** [May 2, 2022, 10:34am UTC](https://forums.freertos.org/t/strdup-does-not-calls-redefined-malloc-free/14972 "2022-05-02T10:34:46Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![BitHacker](https://avatars.discourse-cdn.com/v4/letter/b/b4bc9f/32.png) [@BitHacker](https://forums.freertos.org/u/BitHacker)\
**Post date:** [May 2, 2022, 10:34am UTC](https://forums.freertos.org/t/strdup-does-not-calls-redefined-malloc-free/14972/1 "2022-05-02T10:34:46Z")

</div>

Hello I use freertos with heap-Model heap\_4.  
I have redefined the malloc and free function according the many suggestions you find online

```auto
#include <stdlib.h>

void* malloc(size_t size)
{
    void* ptr = NULL;

    if(size > 0)
    {
        // We simply wrap the FreeRTOS call into a standard form
        ptr = pvPortMalloc(size);
    } // else NULL if there was an error

    return ptr;
}

void free(void* ptr)
{
    if(ptr)
    {
        // We simply wrap the FreeRTOS call into a standard form
        vPortFree(ptr);
    }
}

```

But strdup() does not call the redefined malloc when i run this little test-Programm

```auto
#include <string.h>

static void testMem()
{
   // This works correctly
   char* testA = (char*)malloc(100);
   free(testA);
   
   char* testB = strdup("Banana");
   // Here is the Error. Because perviously strdup Does not call the redefined malloc
   free(testB);
}

```

I can think of two possible solutions ?

1. To rebuild the stdlib to force strdup() to use the redefined malloc ?  
At the moment i am not sure if it is the stdlib and i have no idea how to rebuild it.
2. Use a separte free() function e.g free\_native

```auto
void free_native(void* ptr)
{
   free(ptr)
}

```

Thank you very much for your help.

---

<div class="post-metadata">

**Author:** ![hs2](https://avatars.discourse-cdn.com/v4/letter/h/a4c791/32.png) [@hs2](https://forums.freertos.org/u/hs2)\
**Post date:** [May 2, 2022, 11:17am UTC](https://forums.freertos.org/t/strdup-does-not-calls-redefined-malloc-free/14972/2 "2022-05-02T11:17:55Z")

</div>

(new)lib (also) uses `_malloc_r` internally.  
So you should override the reentrant versions of the allocation symbols, too.  
Note that you should take care about `malloc(_r)`, `free(_r)`, `calloc(_r)` and `realloc(_r)`.

---

<div class="post-metadata">

**Author:** ![richard-damon](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/richard-damon/32/38_2.png) [@richard-damon](https://forums.freertos.org/u/richard-damon)\
**Post date:** [May 2, 2022, 11:57am UTC](https://forums.freertos.org/t/strdup-does-not-calls-redefined-malloc-free/14972/3 "2022-05-02T11:57:32Z")

</div>

C doesn’t “Allow” you to change the standard library reliably. Many implementations (like newlib as Hartmut mentions) make malloc just a “wrapper” function, and something internal is used for the actual work, and this is all ok by the standard.

If your library IS newlib (as is common), you can look into your system and see if it was created with the hooks \_malloc\_lock() / \_malloc\_unlock() compiled in, which if they are, it makes it easy to just make malloc() and free() and the rest “Thread Safe” by a proper definition of them.

---

<div class="post-metadata">

**Author:** ![BitHacker](https://avatars.discourse-cdn.com/v4/letter/b/b4bc9f/32.png) [@BitHacker](https://forums.freertos.org/u/BitHacker)\
**Post date:** [May 2, 2022, 1:08pm UTC](https://forums.freertos.org/t/strdup-does-not-calls-redefined-malloc-free/14972/4 "2022-05-02T13:08:06Z")

</div>

The strdup is defined from newlib in this way:

```auto
char *
_DEFUN (_strdup_r, (reent_ptr, str), 
        struct _reent *reent_ptr _AND
        _CONST char *str)
{
  size_t len = strlen (str) + 1;
  char *copy = _malloc_r (reent_ptr, len);
  if (copy)
    {
      memcpy (copy, str, len);
    }
  return copy;
}

```

so the problem seems that it calls \_malloc\_r(reentr\_ptr,len)  
which is not redefined and therefore does not use pvPortMalloc().

When i try to redefine \_malloc\_r(rentr\_ptr,len) the linker aborts with a “multiple  
definition error”.

---

<div class="post-metadata">

**Author:** ![BitHacker](https://avatars.discourse-cdn.com/v4/letter/b/b4bc9f/32.png) [@BitHacker](https://forums.freertos.org/u/BitHacker)\
**Post date:** [May 2, 2022, 1:14pm UTC](https://forums.freertos.org/t/strdup-does-not-calls-redefined-malloc-free/14972/5 "2022-05-02T13:14:43Z")

</div>

Am i completely wrong when i try to redefine malloc/free to  
secure that heap\_4 works sufficient ?

---

<div class="post-metadata">

**Author:** ![hs2](https://avatars.discourse-cdn.com/v4/letter/h/a4c791/32.png) [@hs2](https://forums.freertos.org/u/hs2)\
**Post date:** [May 2, 2022, 1:41pm UTC](https://forums.freertos.org/t/strdup-does-not-calls-redefined-malloc-free/14972/6 "2022-05-02T13:41:36Z")

</div>

I’m using the `--wrap` GCC linker option to wrap the allocation API mentioned before.  
I think there a some online resources describing this method.

---

<div class="post-metadata">

**Author:** ![richard-damon](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/richard-damon/32/38_2.png) [@richard-damon](https://forums.freertos.org/u/richard-damon)\
**Post date:** [May 2, 2022, 1:57pm UTC](https://forums.freertos.org/t/strdup-does-not-calls-redefined-malloc-free/14972/7 "2022-05-02T13:57:35Z")

</div>

First, replacing library routines is putting you into the domain of you need to really know what you are doing, as it is easy to really break things.

The big point about replacing \_malloc\_r(), is that you also need to replace every other entry point in that module, or you get the sort of error you got. That includes not only \_free\_r() but also things like \_realloc\_r() which FreeRTOS doesn’t have the equivalent of, and maybe even things like \_malloc\_stats\_r() if used. IF you really want to do this, the best course of action is to find what library your implementation uses, and down load the library source for it, and then you can modify that file to do what you want.

As I mentioned, I find it easier, if the implementation is using newlib, to make sure it is using \_\_malloc\_lock() and \_\_malloc\_unlock() and implement those to make malloc thread safe (and then make pvPortMalloc() and vPortFree() call these malloc and free functions). If your newlib wasn’t compiled with that option in, then you need to download the newlib source and build a version with that option enabled.

---

<div class="post-metadata">

**Author:** ![BitHacker](https://avatars.discourse-cdn.com/v4/letter/b/b4bc9f/32.png) [@BitHacker](https://forums.freertos.org/u/BitHacker)\
**Post date:** [May 2, 2022, 5:36pm UTC](https://forums.freertos.org/t/strdup-does-not-calls-redefined-malloc-free/14972/8 "2022-05-02T17:36:00Z")

</div>

i already use the newlib and the flag USE\_NEWLIB\_REENTRANT is Enabled.  
My problem is that strdup does not use malloc but \_maolloc\_r() which i don’t  
want to redefine (this is what you have suggested).

---

<div class="post-metadata">

**Author:** ![hs2](https://avatars.discourse-cdn.com/v4/letter/h/a4c791/32.png) [@hs2](https://forums.freertos.org/u/hs2)\
**Post date:** [May 2, 2022, 6:20pm UTC](https://forums.freertos.org/t/strdup-does-not-calls-redefined-malloc-free/14972/9 "2022-05-02T18:20:16Z")

</div>

Then just don’t use `strdup` - I’d recommend this anyway - and friends using malloc\_r internally and you’ll be fine.

---

<div class="post-metadata">

**Author:** ![richard-damon](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/richard-damon/32/38_2.png) [@richard-damon](https://forums.freertos.org/u/richard-damon)\
**Post date:** [May 2, 2022, 7:04pm UTC](https://forums.freertos.org/t/strdup-does-not-calls-redefined-malloc-free/14972/10 "2022-05-02T19:04:46Z")

</div>

USE\_NEWLIB\_REENTRANT, while helping with some problems, doesn’t make malloc and family thread safe. For that you need to define \_\_malloc\_lock() and \_\_malloc\_unlock() (and make sure your version of newlib uses them). The lock can be just a call to vTaskSuspendAll() and unlock to xTaskResumeAll(), and then a direct call to malloc and family works like the heap\_3.c version.
