📄 tiny-malloc.c
字号:
if (old_real_size - real_size >= sizeof (struct freelist_entry)) { fle newblock = (fle)((size_t)block + real_size); block->size = real_size; newblock->size = old_real_size - real_size; free (&newblock->next); } return block_p;}#endif#ifdef DEFINE_CALLOCvoid *calloc (size_t n, size_t elem_size){ void *result; size_t sz = n * elem_size; result = malloc (sz); if (result != NULL) memset (result, 0, sz); return result;}#endif#ifdef DEFINE_CFREEvoidcfree (void *p){ free (p);}#endif#ifdef DEFINE_MEMALIGNvoid *memalign (size_t align, size_t sz){ fle *nextfree; fle block; /* real_size is the size we actually have to allocate, allowing for overhead and alignment. */ size_t real_size = REAL_SIZE (sz); /* Some sanity checking on 'align'. */ if ((align & (align - 1)) != 0 || align <= 0) return NULL; /* Look for the first block on the freelist that is large enough. */ /* One tricky part is this: We want the result to be a valid pointer to free. That means that there has to be room for a size_t before the block. If there's additional space before the block, it should go on the freelist, or it'll be lost---we could add it to the size of the block before it in memory, but finding the previous block is expensive. */ for (nextfree = &__malloc_freelist; ; nextfree = &(*nextfree)->next) { size_t before_size; size_t old_size; /* If we've run out of free blocks, allocate more space. */ if (! *nextfree) { old_size = real_size; if (MALLOC_DIRECTION < 0) { old_size += M_ALIGN_SUB (((size_t)__malloc_end - old_size + sizeof (size_t)), align); if (! CAN_ALLOC_P (old_size)) return NULL; block = __malloc_end = (void *)((size_t)__malloc_end - old_size); } else { block = __malloc_end; old_size += M_ALIGN ((size_t)__malloc_end + sizeof (size_t), align); if (! CAN_ALLOC_P (old_size)) return NULL; __malloc_end = (void *)((size_t)__malloc_end + old_size); } *nextfree = block; block->size = old_size; block->next = NULL; } else { block = *nextfree; old_size = block->size; } before_size = M_ALIGN (&block->next, align); if (before_size != 0) before_size = sizeof (*block) + M_ALIGN (&(block+1)->next, align); /* If this is the last block on the freelist, and it is too small, enlarge it. */ if (! block->next && old_size < real_size + before_size && __malloc_end == (void *)((size_t)block + block->size)) { if (MALLOC_DIRECTION < 0) { size_t moresize = real_size - block->size; moresize += M_ALIGN_SUB ((size_t)&block->next - moresize, align); if (! CAN_ALLOC_P (moresize)) return NULL; block = __malloc_end = (void *)((size_t)block - moresize); block->next = NULL; block->size = old_size = old_size + moresize; before_size = 0; } else { if (! CAN_ALLOC_P (before_size + real_size - block->size)) return NULL; __malloc_end = (void *)((size_t)block + before_size + real_size); block->size = old_size = before_size + real_size; } /* Two out of the four cases below will now be possible; which two depends on MALLOC_DIRECTION. */ } if (old_size >= real_size + before_size) { /* This block will do. If there needs to be space before it, split the block. */ if (before_size != 0) { fle old_block = block; old_block->size = before_size; block = (fle)((size_t)block + before_size); /* If there's no space after the block, we're now nearly done; just make a note of the size required. Otherwise, we need to create a new free space block. */ if (old_size - before_size <= real_size + sizeof (struct freelist_entry)) { block->size = old_size - before_size; return (void *)&block->next; } else { fle new_block; new_block = (fle)((size_t)block + real_size); new_block->size = old_size - before_size - real_size; if (MALLOC_DIRECTION > 0) { new_block->next = old_block->next; old_block->next = new_block; } else { new_block->next = old_block; *nextfree = new_block; } goto done; } } else { /* If the block found is just the right size, remove it from the free list. Otherwise, split it. */ if (old_size <= real_size + sizeof (struct freelist_entry)) { *nextfree = block->next; return (void *)&block->next; } else { size_t newsize = old_size - real_size; fle newnext = block->next; *nextfree = (fle)((size_t)block + real_size); (*nextfree)->size = newsize; (*nextfree)->next = newnext; goto done; } } } } done: block->size = real_size; return (void *)&block->next;}#endif#ifdef DEFINE_VALLOCvoid *valloc (size_t sz){ return memalign (128, sz);}#endif#ifdef DEFINE_PVALLOCvoid *pvalloc (size_t sz){ return memalign (128, sz + M_ALIGN (sz, 128));}#endif#ifdef DEFINE_MALLINFO#include "malloc.h"struct mallinfo mallinfo (void){ struct mallinfo r; fle fr; size_t free_size; size_t total_size; size_t free_blocks; memset (&r, 0, sizeof (r)); free_size = 0; free_blocks = 0; for (fr = __malloc_freelist; fr; fr = fr->next) { free_size += fr->size; free_blocks++; if (! fr->next) { int atend; if (MALLOC_DIRECTION > 0) atend = (void *)((size_t)fr + fr->size) == __malloc_end; else atend = (void *)fr == __malloc_end; if (atend) r.keepcost = fr->size; } } if (MALLOC_DIRECTION > 0) total_size = (char *)__malloc_end - (char *)&__malloc_start; else total_size = (char *)&__malloc_start - (char *)__malloc_end; #ifdef DEBUG /* Fixme: should walk through all the in-use blocks and see if they're valid. */#endif r.arena = total_size; r.fordblks = free_size; r.uordblks = total_size - free_size; r.ordblks = free_blocks; return r;}#endif#ifdef DEFINE_MALLOC_STATS#include "malloc.h"#include <stdio.h>void malloc_stats(void){ struct mallinfo i; FILE *fp; fp = stderr; i = mallinfo(); fprintf (fp, "malloc has reserved %u bytes between %p and %p\n", i.arena, &__malloc_start, __malloc_end); fprintf (fp, "there are %u bytes free in %u chunks\n", i.fordblks, i.ordblks); fprintf (fp, "of which %u bytes are at the end of the reserved space\n", i.keepcost); fprintf (fp, "and %u bytes are in use.\n", i.uordblks);}#endif#ifdef DEFINE_MALLOC_USABLE_SIZEsize_t malloc_usable_size (void *block_p){ fle block = (fle)((size_t) block_p - offsetof (struct freelist_entry, next)); return block->size - sizeof (size_t);}#endif#ifdef DEFINE_MALLOPTintmallopt (int n, int v){ (void)n; (void)v; return 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -