📄 g++malloc.c
字号:
/* first, re-adjust max used bin */ while (malloc_maxbin >= FIRSTBIN && malloc_maxbin->hd.bk == &(malloc_maxbin->hd)) { malloc_maxbin->dirty = 0; --malloc_maxbin; } for (b = malloc_maxbin; b >= FIRSTBIN; --b) { UPDATE_STATS(++n_malloc_bins); if (b->dirty) { mchunkptr h = &(b->hd); /* head of list */ mchunkptr p = h->fd; /* chunk traverser */ while (p != h) { mchunkptr nextp = p->fd; /* save, in case of relinks */ int consolidated = 0; /* only unlink/relink if consolidated */ mchunkptr t; UPDATE_STATS(++n_malloc_chunks); while (!inuse(t = prev_chunk(p))) /* consolidate backward */ { if (!consolidated) { consolidated = 1; unlink(p); } if (t == nextp) nextp = t->fd; unlink(t); set_size(t, t->size + p->size); p = t; UPDATE_STATS (++n_consol); } while (!inuse(t = next_chunk(p))) /* consolidate forward */ { if (!consolidated) { consolidated = 1; unlink(p); } if (t == nextp) nextp = t->fd; unlink(t); set_size(p, p->size + t->size); UPDATE_STATS (++n_consol); } if (consolidated) { if (p->size >= nb) { /* make it safe to unlink in malloc */ UPDATE_STATS(++n_avail); p->fd = p->bk = p; return p; } else consollink(p); } p = nextp; } b->dirty = 0; } } /* nothing available - sbrk some more */ return malloc_from_sys(nb);}/* Finally, the user-level functions */void* malloc(unsigned int bytes){ unsigned int nb = request2size(bytes); /* padded request size */ mbinptr b = size2bin(nb); /* corresponding bin */ mchunkptr hd = &(b->hd); /* head of its list */ mchunkptr p = hd->fd; /* chunk traverser */ UPDATE_STATS((requested_mem+=bytes, ++n_malloc_bins)); /* Try a (near) exact match in own bin */ /* clean out unusable but consolidatable chunks in bin while traversing */ while (p != hd) { UPDATE_STATS(++n_malloc_chunks); if (p->size >= nb) goto found; else /* try to consolidate; same code as malloc_find_space */ { mchunkptr nextp = p->fd; /* save, in case of relinks */ int consolidated = 0; /* only unlink/relink if consolidated */ mchunkptr t; while (!inuse(t = prev_chunk(p))) /* consolidate backward */ { if (!consolidated) { consolidated = 1; unlink(p); } if (t == nextp) nextp = t->fd; unlink(t); set_size(t, t->size + p->size); p = t; UPDATE_STATS (++n_consol); } while (!inuse(t = next_chunk(p))) /* consolidate forward */ { if (!consolidated) { consolidated = 1; unlink(p); } if (t == nextp) nextp = t->fd; unlink(t); set_size(p, p->size + t->size); UPDATE_STATS (++n_consol); } if (consolidated) { if (p->size >= nb) { /* make it safe to unlink again below */ UPDATE_STATS(++n_avail); p->fd = p->bk = p; goto found; } else consollink(p); } p = nextp; } } b->dirty = 0; /* true if got here */ /* Scan bigger bins for a victim */ while (++b <= malloc_maxbin) { UPDATE_STATS(++n_malloc_bins); if ((p = b->hd.bk) != &(b->hd)) /* no need to check size */ goto found; } /* Consolidate or sbrk */ p = malloc_find_space(nb); if (p == 0) return 0; /* allocation failure */ found: /* Use what we found */ unlink(p); split(p, nb); UPDATE_STATS(do_malloc_stats(p)); return chunk2mem(p);}void free(void* mem){ if (mem != 0) { mchunkptr p = mem2chunk(mem); UPDATE_STATS(do_free_stats(p)); frontlink(p); }}void* calloc(unsigned int n, unsigned int elem_size){ unsigned int sz = n * elem_size; void* p = malloc(sz); bzero(p, sz); return p;};/* This is here for compatibility with older systems */void cfree(void *mem){ free(mem);} unsigned int malloc_usable_size(void* mem){ if (mem == 0) return 0; else { mchunkptr p = (mchunkptr)((char*)(mem) - SIZE_SZ); unsigned int sz = p->size & ~(INUSE); if (p->size == sz || sz != *((int*)((char*)(p) + sz - SIZE_SZ))) return 0; else return sz - MALLOC_MIN_OVERHEAD; }}void* realloc(void* mem, unsigned int bytes){ if (mem == 0) return malloc(bytes); else { unsigned int nb = request2size(bytes); mchunkptr p = mem2chunk(mem); unsigned int oldsize = p->size; int room; mchunkptr nxt; UPDATE_STATS((++n_reallocs, requested_mem += bytes-oldsize)); /* try to expand (even if already big enough), to clean up chunk */ while (!inuse(nxt = next_chunk(p))) { UPDATE_STATS ((malloced_mem += nxt->size, ++n_consol)); unlink(nxt); set_size(p, p->size + nxt->size); } room = p->size - nb; if (room >= 0) { split(p, nb); UPDATE_STATS(malloced_mem -= room); return chunk2mem(p); } else /* do the obvious */ { void* newmem; set_inuse(p); /* don't let malloc consolidate us yet! */ newmem = malloc(nb); bcopy(mem, newmem, oldsize - SIZE_SZ); free(mem); UPDATE_STATS(++n_reallocs_with_copy); return newmem; } }}/* return a pointer to space with at least the alignment requested */void* memalign(unsigned int alignment, unsigned int bytes){ mchunkptr p; unsigned int nb = request2size(bytes); /* find an alignment that both we and the user can live with: */ /* least common multiple guarantees mutual happiness */ unsigned int align = lcm(alignment, MALLOC_MIN_OVERHEAD); unsigned int mask = align - 1; /* call malloc with worst case padding to hit alignment; */ /* we will give back extra */ unsigned int req = nb + align + MINSIZE; void* m = malloc(req); if (m == 0) return m; p = mem2chunk(m); /* keep statistics on track */ UPDATE_STATS(--n_mallocs); UPDATE_STATS(malloced_mem -= p->size); UPDATE_STATS(requested_mem -= req); UPDATE_STATS(requested_mem += bytes); if (((int)(m) & (mask)) != 0) /* misaligned */ { /* find an aligned spot inside chunk */ mchunkptr ap = (mchunkptr)(( ((int)(m) + mask) & -align) - SIZE_SZ); unsigned int gap = (unsigned int)(ap) - (unsigned int)(p); unsigned int room; /* we need to give back leading space in a chunk of at least MINSIZE */ if (gap < MINSIZE) { /* This works since align >= MINSIZE */ /* and we've malloc'd enough total room */ ap = (mchunkptr)( (int)(ap) + align ); gap += align; } if (gap + nb > p->size) /* can't happen unless chunk sizes corrupted */ malloc_user_error(); room = p->size - gap; /* give back leader */ set_size(p, gap); consollink(p); /* use the rest */ p = ap; set_size(p, room); } /* also give back spare room at the end */ split(p, nb); UPDATE_STATS(do_malloc_stats(p)); return chunk2mem(p);}#ifndef sun#include "getpagesize.h"#endifstatic unsigned int malloc_pagesize = 0;void* valloc(unsigned int bytes){ if (malloc_pagesize == 0) malloc_pagesize = getpagesize(); return memalign (malloc_pagesize, bytes);} void malloc_stats(){#ifndef MALLOC_STATS}#else int i; mchunkptr p; double nm = (double)(n_mallocs + n_reallocs); fprintf(stderr, "\nmalloc statistics\n\n"); if (n_mallocs != 0) fprintf(stderr, "requests = %10u total size = %10u\tave = %10u\n", n_mallocs, requested_mem, requested_mem/n_mallocs); if (n_mallocs != 0) fprintf(stderr, "mallocs = %10u total size = %10u\tave = %10u\n", n_mallocs, malloced_mem, malloced_mem/n_mallocs); if (n_frees != 0) fprintf(stderr, "frees = %10u total size = %10u\tave = %10u\n", n_frees, freed_mem, freed_mem/n_frees); if (n_mallocs-n_frees != 0) fprintf(stderr, "in use = %10u total size = %10u\tave = %10u\n", n_mallocs-n_frees, malloced_mem-freed_mem, (malloced_mem-freed_mem) / (n_mallocs-n_frees)); if (max_inuse != 0) fprintf(stderr, "max in use= %10u total size = %10u\tave = %10u\n", max_inuse, max_used_mem, max_used_mem / max_inuse); if (n_avail != 0) fprintf(stderr, "available = %10u total size = %10u\tave = %10u\n", n_avail, sbrked_mem - (malloced_mem-freed_mem), (sbrked_mem - (malloced_mem-freed_mem)) / n_avail); if (n_sbrks != 0) fprintf(stderr, "sbrks = %10u total size = %10u\tave = %10u\n\n", n_sbrks, sbrked_mem, sbrked_mem/ n_sbrks); if (n_reallocs != 0) fprintf(stderr, "reallocs = %10u with copy = %10u\n\n", n_reallocs, n_reallocs_with_copy); if (nm != 0) { fprintf(stderr, "chunks scanned per malloc = %6.3f\n", n_malloc_chunks / nm); fprintf(stderr, "bins scanned per malloc = %6.3f\n", n_malloc_bins / nm); fprintf(stderr, "splits per malloc = %6.3f\n", n_split / nm); fprintf(stderr, "consolidations per malloc = %6.3f\n", n_consol / nm); } fprintf(stderr, "\nfree chunks:\n"); for (i = 0; i < MAXBIN; ++i) { p = av[i].hd.fd; if (p != &(av[i].hd)) { unsigned int count = 1; unsigned int sz = p->size; for (p = p->fd; p != &(av[i].hd); p = p->fd) { if (p->size == sz) ++count; else { fprintf(stderr, "\tsize = %10u count = %5u\n", sz, count); count = 1; sz = p->size; } } fprintf(stderr, "\tsize = %10u count = %5u\n", sz, count); } }}#endif /* MALLOC_STATS */ #endif /* NO_LIBGXX_MALLOC */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -