3 ms·
YL_API void yl_set_allocators(void *(*f_malloc)(size_t), void *(*f_realloc)(void *, size_t), voi
by huhtenberg 13y ago
YL_API void yl_set_allocators(void *(*f_malloc)(size_t),
void *(*f_realloc)(void *, size_t),
void (*f_free)(void *));
Technically, all you need is realloc(), because realloc(ptr, 0) is free and realloc(0, bytes) is malloc.
- adsche 13y ago> realloc(ptr, 0) is free I didn't know that so I went to read up on that. Turns out, this is true for C90, but apparently implementation-defined in C99 [1]. (But as the library creator you could of course define the behaviour that the provided function must have.) [1] http://www.cplusplus.com/reference/cstdlib/realloc/ http://www.cplusplus.com/reference/cstdlib/realloc/
- masklinn 13y ago> realloc(ptr, 0) is free Not quite. POSIX states: > If size is 0, either a null pointer or a unique pointer that can be successfully passed to free() shall be returned. and although FreeBSD's man 3 realloc does not say anything about a 0 size, OpenBSD's man 3 realloc states: > If size is zero and ptr is not a null pointer, the object it points to is freed and a new zero size object is returned. And OSX's states: > If size is zero and ptr is not NULL, a new, minimum sized object is allocated and the original object is freed. So a minimal implementation would need realloc and free, to account for realloc(ptr, 0) allocating.
- huhtenberg 13y ago> Not quite. POSIX Nitpicking without measure is a man's greatest pleasure ;) You are not implementing POSIX. You are providing a hook for the library users and your library will call this hook with (ptr, 0) when it wants to free a memory block. You just declare that your library works that way. Also, if your library wants, it can test provided hook to see if it complies with library's expected behavior and assert/fail if it doesn't. Think about it this way - if you are exposing a way to override realloc() calls in your library, then you will have to specify what your library means when it issues realloc(ptr, 0). So it's perfectly fine to declare that it expects such call to do what free() does, in which case a single realloc hook is sufficient to override all memory operations.
- masklinn 13y ago> Nitpicking without measure is a man's greatest pleasure ;) Pointing out that your assertion is tragically wrong is not nitpicking. > You are not implementing POSIX. Of course not, you're not implementing an OS. You're using POSIX. > You are providing a hook for the library users and your library will call this hook with (ptr, 0) when it wants to free a memory block. You just declare that your library works that way. This means it is not possible to pass through standard allocators to your library without your user having to know precisely how they handle the realloc case. This strikes me as a pretty significant annoyance for any user of said library. Oh, and your library can't rely on the platform's own allocators, so the user must provide an allocator for which he must know how realloc precisely behaves (and possibly wrap it) regardless of spec. > Think about it this way - if you are exposing a way to override realloc() calls in your library, then you will have to specify what your library means when it issues realloc(ptr, 0). If you stick with and expect POSIX semantics, as the name of the hook would imply, you don't have to specify anything and you simplify your library user's job. And think about it this way: if what you want is not realloc, don't call it realloc.