⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tiny-malloc.c

📁 Newlib 嵌入式 C库 标准实现代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  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 + -