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

📄 heap.c

📁 减少内存碎片的malloc分配函数
💻 C
字号:
/* * system specific memory routines * * Copyright 2000 by Gray Watson * * This file is part of the dmalloc package. * * Permission to use, copy, modify, and distribute this software for * any purpose and without fee is hereby granted, provided that the * above copyright notice and this permission notice appear in all * copies, and that the name of Gray Watson not be used in advertising * or publicity pertaining to distribution of the document or software * without specific, written prior permission. * * Gray Watson makes no representations about the suitability of the * software described herein for any purpose.  It is provided "as is" * without express or implied warranty. * * The author may be contacted via http://dmalloc.com/ * * $Id: heap.c,v 1.68 2004/10/12 19:38:57 gray Exp $ *//* * These are the system/machine specific routines for allocating space on the * heap as well as reporting the current position of the heap. */#if HAVE_UNISTD_H# include <unistd.h>				/* for write */#endif#if HAVE_SYS_TYPES_H#  include <sys/types.h>#endif#if HAVE_SYS_MMAN_H#  include <sys/mman.h>				/* for mmap stuff */#endif#define DMALLOC_DISABLE#include "dmalloc.h"#include "conf.h"#include "chunk.h"#include "compat.h"#include "debug_tok.h"#include "error.h"#include "error_val.h"#include "heap.h"#include "dmalloc_loc.h"#define SBRK_ERROR	((char *)-1)		/* sbrk error code *//* exported variables */void		*_dmalloc_heap_low = NULL;	/* base of our heap */void		*_dmalloc_heap_high = NULL;	/* end of our heap *//****************************** local functions ******************************//* * static void *heap_extend * * DESCRIPTION: * * Get more bytes from the system functions. * * RETURNS: * * Success - Valid pointer. * * Failure - NULL * * ARGUMENTS: * * incr -> Number of bytes we need. */static	void	*heap_extend(const int incr){  void	*ret = SBRK_ERROR;  char	*high;  #if INTERNAL_MEMORY_SPACE  {    static char	block_o_bytes[INTERNAL_MEMORY_SPACE];    static char *bounds_p = block_o_bytes + sizeof(block_o_bytes);    static char *block_p = block_o_bytes;        if (block_p + incr >= bounds_p) {      ret = SBRK_ERROR;    }    else {      ret = block_p;      block_p += incr;    }  }#else#if HAVE_MMAP && USE_MMAP#if MAP_ANON  /* if we have and can use mmap, then do so */  ret = mmap(0L, incr, PROT_READ | PROT_WRITE | PROT_EXEC,	     MAP_PRIVATE | MAP_ANON, -1 /* no fd */, 0 /* no offset */);#else#endif  if (ret == MAP_FAILED) {    ret = SBRK_ERROR;  }#else#if HAVE_SBRK  ret = sbrk(incr);#endif /* if HAVE_SBRK */#endif /* if not HAVE_MMAP && USE_MMAP */#endif /* if not INTERNAL_MEMORY_SPACE */    if (ret == SBRK_ERROR) {    if (BIT_IS_SET(_dmalloc_flags, DEBUG_CATCH_NULL)) {      char	str[128];      int	len;      len = loc_snprintf(str, sizeof(str),			 "\r\ndmalloc: critical error: could not extend heap %u more bytes\r\n", incr);      (void)write(STDERR, str, len);      _dmalloc_die(0);    }    dmalloc_errno = ERROR_ALLOC_FAILED;    dmalloc_error("heap_extend");  }    if (_dmalloc_heap_low == NULL || (char *)ret < (char *)_dmalloc_heap_low) {    _dmalloc_heap_low = ret;  }  high = (char *)ret + incr;  if (high > (char *)_dmalloc_heap_high) {    _dmalloc_heap_high = high;  }    if (BIT_IS_SET(_dmalloc_flags, DEBUG_LOG_ADMIN)) {    dmalloc_message("extended heap space by %d bytes [%#lx, %#lx]",		    incr, (unsigned long)_dmalloc_heap_low,		    (unsigned long)_dmalloc_heap_high);  }    return ret;}/**************************** exported functions *****************************//* * int _heap_startup * * DESCRIPTION: * * Initialize heap pointers. * * RETURNS: * * Success - 1 * * Failure - 0 * * ARGUMENTS: * * None. */int	_dmalloc_heap_startup(void){  return 1;}/* * void *_dmalloc_heap_alloc * * DESCRIPTION: * * Function to get memory bytes from the heap. * * RETURNS: * * Success - Valid pointer. * * Failure - NULL * * ARGUMENTS: * * size -> Number of bytes we need. */void	*_dmalloc_heap_alloc(const unsigned int size){  void	*heap_new, *heap_diff;  long	diff;    if (size == 0) {    dmalloc_errno = ERROR_BAD_SIZE;    dmalloc_error("_dmalloc_heap_alloc");    return HEAP_ALLOC_ERROR;  }    while (1) {        /* extend the heap by our size */    heap_new = heap_extend(size);    if (heap_new == SBRK_ERROR) {      return HEAP_ALLOC_ERROR;    }        /* calculate bytes needed to align to block boundary */    diff = (long)heap_new % BLOCK_SIZE;    if (diff == 0) {      /* if we are already aligned then we are all set */      break;    }    diff = BLOCK_SIZE - diff;        /* shift the heap a bit to account for non block alignment */    heap_diff = heap_extend(diff);    if (heap_diff == SBRK_ERROR) {      return HEAP_ALLOC_ERROR;    }        /* if heap-diff went down then our stack grows down */    if ((char *)heap_diff + diff == (char *)heap_new) {      heap_new = heap_diff;      break;    }    else if ((char *)heap_new + size == (char *)heap_diff) {      /* shift up our heap to align with the block */      heap_new = (char *)heap_new + diff;      break;    }        /*     * We may have a wierd sbrk race condition here.  We hope that we     * are not just majorly confused which may mean that we sbrk till     * the cows come home and die from lack of memory.     */        /* start over again */  }    return heap_new;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -