2

When I read the code of cJSON, and have problem understanding the code:

static void *(*cJSON_malloc)(size_t sz) = malloc;

static void (*cJSON_free)(void *ptr) = free;
Sled
  • 18,541
  • 27
  • 119
  • 168
colin
  • 41
  • 6
  • 1
    Those are creating function pointers as aliases for malloc and free. This would allow someone to replace mallloc/free with some other heap manager code. – Hot Licks Sep 03 '13 at 11:48
  • @HotLicks I dont understand why they do this. The same will happen if we use 'cJSON_malloc' and 'malloc'. What we achieve if we simply rename 'library functions' ? – rakeshNS Sep 03 '13 at 11:53
  • 1
    @rakeshNS If at some point you decide to use some custom heap management functions instead of the standard `malloc` and `free`, you only have to change these two lines of code and make `cJSON_malloc` and `cJSON_free` point to the new functions, instead of replacing every use of `malloc` and `free` in the code with the new functions. – Ionut Sep 03 '13 at 12:25
  • @rakeshNS as Hot Licks said it makes it easy for someone to replace use of the standard library functions with their own implementation. – Nigel Harper Sep 03 '13 at 12:25
  • 2
    Standard uses for malloc-library hooks include simulating allocation failures (especially during testing) or adding more stringent debugging versions of malloc/free that scrutinize the requests and check that what is freed was allocated and that no trampling occurred outside the allocated bounds, or that the reallocation always gives you a new address back so no code gets complacent and assumes `realloc()` gives back the original address, etc. – Jonathan Leffler Sep 03 '13 at 15:10

3 Answers3

2

This is just function pointers. By doing this way we can use 'cJSON_malloc' in place of malloc and cJSON_free in place of free.

rakeshNS
  • 4,227
  • 4
  • 28
  • 42
2

Those are function pointer initialization. For example:

static void *(*cJSON_malloc)(size_t sz) = malloc;

is equivalent to:

typedef void *(*cJSON_malloc_type)(size_t sz);
static cJSON_malloc_type cJSON_malloc = malloc;

I hope this is more understandable.

lulyon
  • 6,707
  • 7
  • 32
  • 49
1

As the others have already mentioned, these are function pointers. With those you can change the allocator and deallocator function at runtime.

There are many reasons why you would want to use a different allocator than malloc and free, for example:

  • Performance
  • Debugging
  • Security
  • Special Device Memory

Example allocator that prints every allocation and deallocation to stdout:

void *my_malloc(size_t size) {
    void *pointer = malloc(size);
    printf("Allocated %zu bytes at %p\n", size, pointer);
    return pointer;
}

void my_free(void *pointer) {
    free(pointer);
    printf("Freed %p\n", pointer);
}

void change_allocators() {
    cJSON_hooks custom_allocators = {my_malloc, my_free};
    cJSON_InitHooks(custom_allocators);
}
FSMaxB
  • 2,280
  • 3
  • 22
  • 41