void pblockpool::dealloc(void *ptr) { if (IMMEDIATE_MODE) free(ptr); else { for (memblock *p = m_first; p != NULL; p = p->next) { if (ptr >= &p->data[0] && ptr < &p->data[p->size]) { p->allocated -= 1; if (p->allocated < 0) std::fprintf(stderr, "nstring: memory corruption - crash likely\n"); if (p->allocated == 0) { //std::printf("Block entirely freed\n"); p->remaining = p->size; p->cur = &p->data[0]; } // shutting down ? if (m_shutdown) resetmem(); // try to free blocks return; } } std::fprintf(stderr, "nstring: string <%p> not found on free\n", ptr); } }
/* Travers the groups and put the elements into buckets. The parameter pos indicates the current position in the string. To be able to skip groups that are already sorted we keep track of the previous group. Also, the previously read character is recorded. In this way it is possible to move the elements in blocks consisting of strings that have a common character in position pos. Furthermore, a group that is not split during this phase is left behind and not put into a bucket. */ static void intobuckets(group g, bucket b[], int pos) { group prevg; character ch, prevch; boolean split; list tail, tailn; int size; resetmem(bucketmem); for (prevg = g, g = g->nextunf ; g; g = g->nextunf) { if (g->finis) {prevg->nextunf = g->nextunf; continue;} tail = g->head; split = FALSE; prevch = CHAR(tail->str, pos); size = 1; for ( ; (tailn = tail->next); tail = tailn) { ch = CHAR(tailn->str, pos); size++; if (ch == prevch) continue; intobucket(b+prevch, g->head, tail, size-1, g); g->head = tailn; split = TRUE; prevch = ch; size = 1; } if (split) { intobucket(b+prevch, g->head, tail, size, g); g->head = NULL; prevg = g; } else if (IS_ENDMARK(prevch)) prevg->nextunf = g->nextunf; else prevg = g; } }