Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it portable to take the address of malloc(), realloc() and free()?

Tags:

c

standards

Per the standard, is it safe to take the address of malloc(), realloc(), and free()?

For example,

#include <stdlib.h>
void * (*my_malloc)(size_t) = &malloc;

Corollary, is it possible in standards-compliant C that the implementation uses a macro for malloc/realloc/free?

like image 285
Qix - MONICA WAS MISTREATED Avatar asked Jan 09 '21 05:01

Qix - MONICA WAS MISTREATED


People also ask

How do we use malloc() and free() functions?

Let’s see how we use malloc () and free () functions. How do we use the malloc () function? malloc () function is a Dynamic Memory Allocation function that allocates a block of size bytes from the memory heap. It allows a program to allocate memory explicitly as it is needed, and in the exact amounts needed. The allocation is from the main memory.

What is the difference between malloc and realloc?

As we can see, copying manually with memcpy is always slower than realloc, because in this scenario malloc is guaranteed to allocate new memory and you're forced to copy the data in every allocation, which shows us that realloc is indeed reusing the same address and enlarging the block size in some cases.

What happens if the argument size == 0 in malloc?

If the argument size == 0, malloc returns NULL. How can I use malloc () and free () functions? The free () function is a Dynamic Memory Allocation function that frees allocated block. Free () deallocates a memory block allocated by a previous call to calloc , malloc, or realloc.

What is realloc () function in C++?

realloc () function modifies the allocated memory size by malloc () and calloc () functions to new size. If memory is not sufficient for malloc () or calloc (), you can reallocate the memory by realloc () function.


Video Answer


1 Answers

Yes, this is safe. The standard library is allowed to define function-like macros for any of its functions, but they must also be available as functions.

C17 7.1.4 (1)

Any function declared in a header may be additionally implemented as a function-like macro defined in the header, so if a library function is declared explicitly when its header is included, one of the techniques shown below can be used to ensure the declaration is not affected by such a macro. Any macro definition of a function can be suppressed locally by enclosing the name of the function in parentheses, because the name is then not followed by the left parenthesis that indicates expansion of a macro function name. For the same syntactic reason, it is permitted to take the address of a library function even if it is also defined as a macro. [189]

[189] This means that an implementation shall provide an actual function for each library function, even if it also provides a macro for that function.

So in short, the library's header is allowed to have something like

void *malloc(size_t);
#define malloc(s) __fancy_internal_malloc((s) + 47 | 0x14 * 3)

and so then you can do any of

void *p = malloc(10); // invokes the macro if there is one
void *q = (malloc)(10); // definitely calls the function, not the macro
void *(*allocator)(size_t) = &malloc; // takes address of the function
#undef malloc
void *r = malloc(10); // definitely the function

Of course, the function and the macro must both provide whatever behavior the standard promises (though as Eric Postpischil comments, they do not have to behave identically so long as each is conformant). In particular, it must be safe to allocate with the macro and free with the function, or vice versa. Also, such a macro must evaluate each of its arguments exactly once, so p = malloc(s++); is safe for either the function or the macro.

like image 163
Nate Eldredge Avatar answered Oct 05 '22 04:10

Nate Eldredge