I do not have a device to test on, so I'm basing this entirely off of information from the docs and from here on the forum:
I'm writing an app in C that uses a few libraries to accomplish core tasks, and one of the libraries uses calloc
internally. I read here that calloc
does not work on device, so in the interest of solving as many problems as I can ahead of receiving my Playdate, I thought I'd try overriding calloc
with an implementation that used malloc
and memset
internally, similarly to how the SDK's setup.c
redefines malloc
/free
/realloc
with implementations that use playdate->system->realloc
. (somewhat related: C API: Why isn't setup.c included in Simulator builds?)
I used DidierMalenfant's example implementation, swapping the custom pd_malloc
out for malloc
. Following the format in setup.c, I define the implementation as _calloc_r
if targeting the Playdate hardware, or as calloc
if instead targeting the Simulator. This seems to work in the Simulator, but I'd greatly appreciate it if someone could confirm that this workaround works on hardware. Worst case scenario, if redefining _calloc_r
on hardware doesn't end up working, I can just set the one library to use the custom calloc
implementation directly. I'd also love to know what happens on hardware when calloc
is used without being redefined.
Full implementation:
#include <pd_api.h>
// https://devforum.play.date/t/a-list-of-helpful-libraries-and-code/221/85
#if TARGET_PLAYDATE
void* _calloc_r(struct _reent* _REENT, size_t nb_of_items, size_t item_size)
#else
void* calloc(size_t nb_of_items, size_t item_size)
#endif
{
if (item_size && (nb_of_items > (SIZE_MAX / item_size))) {
return NULL;
}
size_t size = nb_of_items * item_size;
void* memory = malloc(size);
if(memory != NULL) {
memset(memory, 0, size);
}
return memory;
}
Thanks!