3e29ad0059ebf3c9b781ac5317e692ae2a2687bb braney Tue Jan 14 23:31:45 2020 -0800 hgCollection fiddles with the settingsHash of trackDb, which might be cached and made up of memory that shouldn't be freed. Copy the hash before fiddling with it. Found a bug in lmCloneHash (wasn't setting hash->lm correctly, so increment trackDb version just to make sure cache will be cleared. diff --git src/lib/localmem.c src/lib/localmem.c index 7030a53..4d8b0d9 100644 --- src/lib/localmem.c +++ src/lib/localmem.c @@ -1,26 +1,27 @@ /* LocalMem.c - local memory routines. * * These routines are meant for the sort of scenario where * a lot of little to medium size pieces of memory are * allocated, and then disposed of all at once. * * This file is copyright 2002 Jim Kent, but license is hereby * granted for all use - public, private or commercial. */ #include "common.h" +#include "hash.h" #include "localmem.h" struct lm { struct lmBlock *blocks; size_t blockSize; size_t allignMask; size_t allignAdd; boolean doMemoryAllocs; // if true, do our own memory allocs, otherwise use passed in pointer }; struct lmBlock { struct lmBlock *next; @@ -279,15 +280,51 @@ ref->val = val; slAddHead(pRefList, ref); } char *lmJoinStrings(struct lm *lm, char *a, char *b) /* Return concatenation of a and b allocated in lm */ { int aSize = strlen(a); int resSize = aSize + strlen(b) + 1; char *output = lmAlloc(lm, resSize); strcpy(output, a); strcpy(output + aSize, b); return output; } +static struct hashEl *lmCloneHashElList(struct lm *lm, struct hashEl *list) +/* Clone a list of hashEl's. */ +{ +struct hashEl *newList = NULL; + +for(; list; list = list->next) + { + struct hashEl *hel = lmAlloc(lm, sizeof(struct hashEl)); + slAddHead(&newList, hel); + hel->name = lmCloneString(lm, list->name); + hel->val = lmCloneString(lm, (char *)list->val); // we're assuming that the values are strings + hel->hashVal = list->hashVal; + } + +return newList; +} + +struct hash *lmCloneHash(struct lm *lm, struct hash *hash) +/* Clone a hash into local memory. ASSUMES VALUES ARE STRINGS */ +{ +struct hash *newHash = lmAlloc(lm, sizeof(struct hash)); + +*newHash = *hash; +newHash->lm = lm; +newHash->ownLm = TRUE; +newHash->next = NULL; +lmAllocArray(lm, newHash->table, hash->size); + +int ii; +for(ii=0; ii < hash->size; ii++) + if (hash->table[ii] != NULL) + newHash->table[ii] = lmCloneHashElList(lm, hash->table[ii]); + +return newHash; +} +