Merge branch 'use-free' of https://github.com/adurdin/stb into working

This commit is contained in:
Sean Barrett 2019-06-17 05:17:36 -07:00
commit 258c6e1f50

View File

@ -41,6 +41,15 @@ COMPILE-TIME OPTIONS
hash table insertion about 20% slower on 4- and 8-byte keys, 5% slower on
64-byte keys, and 10% slower on 256-byte keys on my test computer.
#define STBDS_REALLOC better_realloc
#define STBDS_FREE better_free
These defines only need to be set in the file containing #define STB_DS_IMPLEMENTATION.
By default stb_ds uses stdlib realloc() and free() for memory management. You can
substitute your own functions (with the same signatures) instead by defining these
symbols. You must either define both, or neither.
LICENSE
Placed in the public domain and also MIT licensed.
@ -232,7 +241,7 @@ DOCUMENTATION
void sh_new_strdup(T*);
Overwrites the existing pointer with a newly allocated
string hashmap which will automatically allocate and free
each string key using malloc/free
each string key using realloc/free
sh_new_arena
void sh_new_arena(T*);
@ -321,7 +330,6 @@ CREDITS
#ifndef INCLUDE_STB_DS_H
#define INCLUDE_STB_DS_H
#include <stdlib.h>
#include <stddef.h>
#include <string.h>
@ -374,6 +382,16 @@ CREDITS
#define stralloc stbds_stralloc
#define strreset stbds_strreset
#endif
#if defined(STBDS_REALLOC) && !defined(STBDS_FREE) || !defined(STBDS_REALLOC) && defined(STBDS_FREE)
#error "You must define both STBDS_REALLOC and STBDS_FREE, or neither."
#endif
#if !defined(STBDS_REALLOC) && !defined(STBDS_FREE)
#include <stdlib.h>
#define STBDS_REALLOC realloc
#define STBDS_FREE free
#endif
#ifdef __cplusplus
extern "C" {
#endif
@ -405,6 +423,7 @@ extern void * stbds_hmput_default(void *a, size_t elemsize);
extern void * stbds_hmput_key(void *a, size_t elemsize, void *key, size_t keysize, int mode);
extern void * stbds_hmdel_key(void *a, size_t elemsize, void *key, size_t keysize, size_t keyoffset, int mode);
extern void * stbds_shmode_func(size_t elemsize, int mode);
extern void stbds_free(void *p);
#ifdef __cplusplus
}
@ -449,7 +468,7 @@ extern void * stbds_shmode_func(size_t elemsize, int mode);
#define stbds_arrpop(a) (stbds_header(a)->length--, (a)[stbds_header(a)->length])
#define stbds_arraddn(a,n) (stbds_arrmaybegrow(a,n), stbds_header(a)->length += (n))
#define stbds_arrlast(a) ((a)[stbds_header(a)->length-1])
#define stbds_arrfree(a) ((void) ((a) ? realloc(stbds_header(a),0) : 0), (a)=NULL)
#define stbds_arrfree(a) ((void) ((a) ? stbds_free(stbds_header(a)) : (void)0), (a)=NULL)
#define stbds_arrdel(a,i) stbds_arrdeln(a,i,1)
#define stbds_arrdeln(a,i,n) (memmove(&(a)[i], &(a)[(i)+(n)], sizeof *(a) * (stbds_header(a)->length-(n)-(i))), stbds_header(a)->length -= (n))
#define stbds_arrdelswap(a,i) ((a)[i] = stbds_arrlast(a), stbds_header(a)->length -= 1)
@ -623,6 +642,11 @@ size_t stbds_rehash_items;
#define STBDS_STATS(x)
#endif
void stbds_free(void *p)
{
STBDS_FREE(p);
}
//
// stbds_arr implementation
//
@ -645,7 +669,7 @@ void *stbds_arrgrowf(void *a, size_t elemsize, size_t addlen, size_t min_cap)
else if (min_cap < 4)
min_cap = 4;
b = realloc((a) ? stbds_header(a) : 0, elemsize * min_cap + sizeof(stbds_array_header));
b = STBDS_REALLOC((a) ? stbds_header(a) : 0, elemsize * min_cap + sizeof(stbds_array_header));
b = (char *) b + sizeof(stbds_array_header);
if (a == NULL) {
stbds_header(b)->length = 0;
@ -737,7 +761,7 @@ static size_t stbds_log2(size_t slot_count)
static stbds_hash_index *stbds_make_hash_index(size_t slot_count, stbds_hash_index *ot)
{
stbds_hash_index *t;
t = (stbds_hash_index *) realloc(0,(slot_count >> STBDS_BUCKET_SHIFT) * sizeof(stbds_hash_bucket) + sizeof(stbds_hash_index) + STBDS_CACHE_LINE_SIZE-1);
t = (stbds_hash_index *) STBDS_REALLOC(0,(slot_count >> STBDS_BUCKET_SHIFT) * sizeof(stbds_hash_bucket) + sizeof(stbds_hash_index) + STBDS_CACHE_LINE_SIZE-1);
t->storage = (stbds_hash_bucket *) STBDS_ALIGN_FWD((size_t) (t+1), STBDS_CACHE_LINE_SIZE);
t->slot_count = slot_count;
t->slot_count_log2 = stbds_log2(slot_count);
@ -1053,7 +1077,6 @@ static int stbds_is_key_equal(void *a, size_t elemsize, void *key, size_t keysiz
#define STBDS_HASH_TO_ARR(x,elemsize) ((char*) (x) - (elemsize))
#define STBDS_ARR_TO_HASH(x,elemsize) ((char*) (x) + (elemsize))
#define STBDS_FREE(x) realloc(x,0)
#define stbds_hash_table(a) ((stbds_hash_index *) stbds_header(a)->hash_table)
@ -1374,7 +1397,7 @@ static char *stbds_strdup(char *str)
// to keep replaceable allocator simple, we don't want to use strdup.
// rolling our own also avoids problem of strdup vs _strdup
size_t len = strlen(str)+1;
char *p = (char*) realloc(0, len);
char *p = (char*) STBDS_REALLOC(0, len);
memmove(p, str, len);
return p;
}
@ -1407,7 +1430,7 @@ char *stbds_stralloc(stbds_string_arena *a, char *str)
// note that we still advance string_block so block size will continue
// increasing, so e.g. if somebody only calls this with 1000-long strings,
// eventually the arena will start doubling and handling those as well
stbds_string_block *sb = (stbds_string_block *) realloc(0, sizeof(*sb)-8 + len);
stbds_string_block *sb = (stbds_string_block *) STBDS_REALLOC(0, sizeof(*sb)-8 + len);
memmove(sb->storage, str, len);
if (a->storage) {
// insert it after the first element, so that we don't waste the space there
@ -1420,7 +1443,7 @@ char *stbds_stralloc(stbds_string_arena *a, char *str)
}
return sb->storage;
} else {
stbds_string_block *sb = (stbds_string_block *) realloc(0, sizeof(*sb)-8 + blocksize);
stbds_string_block *sb = (stbds_string_block *) STBDS_REALLOC(0, sizeof(*sb)-8 + blocksize);
sb->next = a->storage;
a->storage = sb;
a->remaining = blocksize;
@ -1440,7 +1463,7 @@ void stbds_strreset(stbds_string_arena *a)
x = a->storage;
while (x) {
y = x->next;
realloc(x,0);
STBDS_FREE(x);
x = y;
}
memset(a, 0, sizeof(*a));