📄 malloc.c
字号:
#if DUMP_UNFREED_SUMMARY_ONLY 0#else 1#endif ); } #if LOG_PNT_TIMEVAL { TIMEVAL_TYPE now; char time_buf1[64], time_buf2[64]; GET_TIMEVAL(now); dmalloc_message("ending time = %s, elapsed since start = %s", _dmalloc_ptimeval(&now, time_buf1, sizeof(time_buf1), 0), _dmalloc_ptimeval(&now, time_buf2, sizeof(time_buf2), 1)); }#else#if HAVE_TIME /* NOT LOG_PNT_TIME */ { TIME_TYPE now; char time_buf1[64], time_buf2[64]; now = time(NULL); dmalloc_message("ending time = %s, elapsed since start = %s", _dmalloc_ptime(&now, time_buf1, sizeof(time_buf1), 0), _dmalloc_ptime(&now, time_buf2, sizeof(time_buf2), 1)); }#endif#endif in_alloc_b = 0; #if LOCK_THREADS unlock_thread();#endif /* NOTE: do not set enabled_b to false here */}#if FINI_DMALLOC/* * void __fini_dmalloc * * DESCRIPTION: * * Automatic function to close dmalloc supported by some operating * systems. Pretty cool OS/compiler hack. By default it is not * necessary because we use atexit() and on_exit() to register the * close functions which are more portable. * * RETURNS: * * None. * * ARGUMENTS: * * None. */void __fini_dmalloc(void){ dmalloc_shutdown();}#endif/* * DMALLOC_PNT dmalloc_malloc * * DESCRIPTION: * * Allocate and return a memory block of a certain size. * * RETURNS: * * Success - Valid pointer. * * Failure - 0L * * ARGUMENTS: * * file -> File-name or return-address of the caller. * * line -> Line-number of the caller. * * size -> Number of bytes requested. * * func_id -> Function-id to identify the type of call. See * dmalloc.h. * * alignment -> To align the new block to a certain number of bytes, * set this to a value greater than 0. * * xalloc_b -> If set to 1 then print an error and exit if we run out * of memory. */DMALLOC_PNT dmalloc_malloc(const char *file, const int line, const DMALLOC_SIZE size, const int func_id, const DMALLOC_SIZE alignment, const int xalloc_b){ void *new_p; DMALLOC_SIZE align; #if DMALLOC_SIZE_UNSIGNED == 0 if (size < 0) { dmalloc_errno = ERROR_BAD_SIZE; dmalloc_error("malloc"); if (tracking_func != NULL) { tracking_func(file, line, func_id, size, alignment, NULL, NULL); } return MALLOC_ERROR; }#endif if (! dmalloc_in(file, line, 1)) { if (tracking_func != NULL) { tracking_func(file, line, func_id, size, alignment, NULL, NULL); } return MALLOC_ERROR; } if (alignment == 0) { if (func_id == DMALLOC_FUNC_VALLOC) { align = BLOCK_SIZE; } else { align = 0; } } else if (alignment >= BLOCK_SIZE) { align = BLOCK_SIZE; } else { /* * NOTE: Currently, there is no support in the library for * memalign on less than block boundaries. It will be non-trivial * to support valloc with fence-post checking and the lack of the * flag width for dblock allocations. */ if (! memalign_warn_b) { dmalloc_message("WARNING: memalign called without library support"); memalign_warn_b = 1; } align = 0; /* align = alignment */ } new_p = _dmalloc_chunk_malloc(file, line, size, func_id, align); check_pnt(file, line, new_p, "malloc"); dmalloc_out(); if (tracking_func != NULL) { tracking_func(file, line, func_id, size, alignment, NULL, new_p); } if (xalloc_b && new_p == NULL) { char mess[1024], desc[128]; (void)loc_snprintf(mess, sizeof(mess), "Out of memory while allocating %d bytes from '%s'\n", size, _dmalloc_chunk_desc_pnt(desc, sizeof(desc), file, line)); (void)write(STDERR, mess, strlen(mess)); _exit(1); } return new_p;}/* * DMALLOC_PNT dmalloc_realloc * * DESCRIPTION: * * Resizes and old pointer to a new number of bytes. * * RETURNS: * * Success - Valid pointer. * * Failure - 0L * * ARGUMENTS: * * file -> File-name or return-address of the caller. * * line -> Line-number of the caller. * * old_pnt -> Pointer to an existing memory chunk that we are * resizing. If this is NULL then it basically does a malloc. * * new_size -> New number of bytes requested for the old pointer. * * func_id -> Function-id to identify the type of call. See * dmalloc.h. * * xalloc_b -> If set to 1 then print an error and exit if we run out * of memory. */DMALLOC_PNT dmalloc_realloc(const char *file, const int line, DMALLOC_PNT old_pnt, DMALLOC_SIZE new_size, const int func_id, const int xalloc_b){ void *new_p; #if DMALLOC_SIZE_UNSIGNED == 0 if (new_size < 0) { dmalloc_errno = ERROR_BAD_SIZE; dmalloc_error("realloc"); if (tracking_func != NULL) { tracking_func(file, line, func_id, new_size, 0, old_pnt, NULL); } return MALLOC_ERROR; }#endif if (! dmalloc_in(file, line, 1)) { if (tracking_func != NULL) { tracking_func(file, line, func_id, new_size, 0, old_pnt, NULL); } return REALLOC_ERROR; } check_pnt(file, line, old_pnt, "realloc-in"); #if ALLOW_REALLOC_NULL if (old_pnt == NULL) { int new_func_id; /* shift the function id to be calloc or malloc */ if (func_id == DMALLOC_FUNC_RECALLOC) { new_func_id = DMALLOC_FUNC_CALLOC; } else { new_func_id = DMALLOC_FUNC_MALLOC; } new_p = _dmalloc_chunk_malloc(file, line, new_size, new_func_id, 0); } else#endif#if ALLOW_REALLOC_SIZE_ZERO if (new_size == 0) { /* * If realloc(old_pnt, 0) then free(old_pnt). Thanks to Stefan * Froehlich for patiently pointing that the realloc in just * about every Unix has this functionality. */ (void)_dmalloc_chunk_free(file, line, old_pnt, func_id); new_p = NULL; } else#endif new_p = _dmalloc_chunk_realloc(file, line, old_pnt, new_size, func_id); if (new_p != NULL) { check_pnt(file, line, new_p, "realloc-out"); } dmalloc_out(); if (tracking_func != NULL) { tracking_func(file, line, func_id, new_size, 0, old_pnt, new_p); } if (xalloc_b && new_p == NULL) { char mess[1024], desc[128]; (void)loc_snprintf(mess, sizeof(mess), "Out of memory while reallocating %d bytes from '%s'\n", new_size, _dmalloc_chunk_desc_pnt(desc, sizeof(desc), file, line)); (void)write(STDERR, mess, strlen(mess)); _exit(1); } return new_p;}/* * int dmalloc_free * * DESCRIPTION: * * Release a pointer back into the heap. * * RETURNS: * * Success - FREE_NOERROR * * Failure - FREE_ERROR * * Note: many operating systems define free to return (void) so this * return value may be filtered. Dumb. * * ARGUMENTS: * * file -> File-name or return-address of the caller. * * line -> Line-number of the caller. * * pnt -> Existing pointer we are freeing. * * func_id -> Function-id to identify the type of call. See * dmalloc.h. */int dmalloc_free(const char *file, const int line, DMALLOC_PNT pnt, const int func_id){ int ret; if (! dmalloc_in(file, line, 1)) { if (tracking_func != NULL) { tracking_func(file, line, func_id, 0, 0, pnt, NULL); } return FREE_ERROR; } check_pnt(file, line, pnt, "free"); ret = _dmalloc_chunk_free(file, line, pnt, func_id); dmalloc_out(); if (tracking_func != NULL) { tracking_func(file, line, DMALLOC_FUNC_FREE, 0, 0, pnt, NULL); } return ret;}/* * DMALLOC_PNT dmalloc_strdup * * DESCRIPTION: * * Allocate and return an allocated block of memory holding a copy of * a string. * * RETURNS: * * Success - Valid pointer. * * Failure - 0L * * ARGUMENTS: * * file -> File-name or return-address of the caller. * * line -> Line-number of the caller. * * string -> String we are duplicating. * * xalloc_b -> If set to 1 then print an error and exit if we run out * of memory. */char *dmalloc_strdup(const char *file, const int line, const char *string, const int xalloc_b){ DMALLOC_SIZE len; char *new_string; /* check the arguments */ if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { if (! dmalloc_verify_pnt(file, line, "strdup", string, 0 /* not exact */, -1)) { dmalloc_message("bad pointer argument found in strdup"); } } len = strlen(string) + 1; new_string = dmalloc_malloc(file, line, len, DMALLOC_FUNC_STRDUP, 0 /* no alignment */, xalloc_b); if (new_string != NULL) { strncpy(new_string, string, len - 1); new_string[len - 1] = '\0'; } return new_string;}/*************************** external memory calls ***************************//* * DMALLOC_PNT malloc * * DESCRIPTION: * * Overloading the malloc(3) function. Allocate and return a memory * block of a certain size. * * RETURNS: * * Success - Valid pointer. * * Failure - 0L * * ARGUMENTS: * * size -> Number of bytes requested. */#undef mallocDMALLOC_PNT malloc(DMALLOC_SIZE size){ char *file; GET_RET_ADDR(file); return dmalloc_malloc(file, DMALLOC_DEFAULT_LINE, size, DMALLOC_FUNC_MALLOC, 0 /* no alignment */, 0 /* no xalloc messages */);}/* * DMALLOC_PNT malloc * * DESCRIPTION: * * Overloading the calloc(3) function. Returns a block of zeroed memory. * * RETURNS: * * Success - Valid pointer. * * Failure - 0L * * ARGUMENTS: * * num_elements -> Number of elements being allocated. * * size -> The number of bytes in each element. */#undef callocDMALLOC_PNT calloc(DMALLOC_SIZE num_elements, DMALLOC_SIZE size){ DMALLOC_SIZE len = num_elements * size; char *file; GET_RET_ADDR(file); return dmalloc_malloc(file, DMALLOC_DEFAULT_LINE, len, DMALLOC_FUNC_CALLOC, 0 /* no alignment */, 0 /* no xalloc messages */);}/* * DMALLOC_PNT realloc * * DESCRIPTION: * * Overload of realloc(3). Resizes and old pointer to a new number of * bytes. * * RETURNS: * * Success - Valid pointer. * * Failure - 0L * * ARGUMENTS: * * old_pnt -> Pointer to an existing memory chunk that we are * resizing. If this is NULL then it basically does a malloc. * * new_size -> New number of bytes requested for the old pointer. */#undef reallocDMALLOC_PNT realloc(DMALLOC_PNT old_pnt, DMALLOC_SIZE new_size){ char *file; GET_RET_ADDR(file); return dmalloc_realloc(file, DMALLOC_DEFAULT_LINE, old_pnt, new_size, DMALLOC_FUNC_REALLOC, 0 /* no xalloc messages */);}/* * DMALLOC_PNT recalloc * * DESCRIPTION: * * Overload of recalloc(3) which exists on some systems. Resizes and * old pointer to a new number of bytes. If we are expanding, then * any new bytes will be zeroed. * * RETURNS: * * Success - Valid pointer. * * Failure - 0L * * ARGUMENTS: * * old_pnt -> Pointer to an existing memory chunk that we are * resizing. * * new_size -> New number of bytes requested for the old pointer. */#undef recallocDMALLOC_PNT recalloc(DMALLOC_PNT old_pnt, DMALLOC_SIZE new_size){ char *file; GET_RET_ADDR(file); return dmalloc_realloc(file, DMALLOC_DEFAULT_LINE, old_pnt, new_size, DMALLOC_FUNC_RECALLOC, 0 /* no xalloc messages */);}/* * DMALLOC_PNT memalign * * DESCRIPTION: * * Overloading the memalign(3) function. Allocate and return a memory * block of a certain size which have been aligned to a certain * alignment. * * RETURNS: * * Success - Valid pointer. * * Failure - 0L * * ARGUMENTS: * * alignment -> Value to which the allocation must be aligned. This * should probably be a multiple of 2 with a maximum value equivalent * to the block-size which is often 1k or 4k. * * size -> Number of bytes requested. */#undef memalignDMALLOC_PNT memalign(DMALLOC_SIZE alignment, DMALLOC_SIZE size){ char *file; GET_RET_ADDR(file); return dmalloc_malloc(file, DMALLOC_DEFAULT_LINE, size, DMALLOC_FUNC_MEMALIGN, alignment, 0 /* no xalloc messages */);}/* * DMALLOC_PNT valloc * * DESCRIPTION: * * Overloading the valloc(3) function. Allocate and return a memory * block of a certain size which have been aligned to page boundaries * which are often 1k or 4k. * * RETURNS: * * Success - Valid pointer. * * Failure - 0L * * ARGUMENTS: * * size -> Number of bytes requested. */#undef vallocDMALLOC_PNT valloc(DMALLOC_SIZE size){ char *file; GET_RET_ADDR(file); return dmalloc_malloc(file, DMALLOC_DEFAULT_LINE, size, DMALLOC_FUNC_VALLOC, BLOCK_SIZE, 0 /* no xalloc messages */);}#ifndef DMALLOC_STRDUP_MACRO/* * DMALLOC_PNT strdup * * DESCRIPTION: * * Overload of strdup(3). Allocate and return an allocated block of * memory holding a copy of a string. * * RETURNS: * * Success - Valid pointer. * * Failure - 0L * * ARGUMENTS: * * string -> String we are duplicating. */#undef strdupchar *strdup(const char *string){ int len; char *buf, *file; GET_RET_ADDR(file); /* check the arguments */ if (BIT_IS_SET(_dmalloc_flags, DEBUG_CHECK_FUNCS)) { if (! dmalloc_verify_pnt(file, 0 /* no line */, "strdup", string, 0 /* not exact */, -1)) { dmalloc_message("bad pointer argument found in strdup"); } } /* len + \0 */ len = strlen(string) + 1; buf = dmalloc_malloc(file, DMALLOC_DEFAULT_LINE, len, DMALLOC_FUNC_STRDUP, 0 /* no alignment */, 0 /* no xalloc messages */); if (buf != NULL) { (void)memcpy(buf, string, len); } return buf;}#endif/* * DMALLOC_FREE_RET free * * DESCRIPTION: * * Release a pointer back into the heap. * * RETURNS: * * Returns FREE_ERROR, FREE_NOERROR or void depending on whether STDC * is defined by your compiler. * * ARGUMENTS: * * pnt -> Existing pointer we are freeing. */#undef freeDMALLOC_FREE_RET free(DMALLOC_PNT pnt){ char *file; int ret; GET_RET_ADDR(file); ret = dmalloc_free(file, DMALLOC_DEFAULT_LINE, pnt, DMALLOC_FUNC_FREE); #if (defined(__STDC__) && __STDC__ == 1) || defined(__cplusplus) || defined(STDC_HEADERS)#else return ret;#endif}/* * DMALLOC_FREE_RET cfree * * DESCRIPTION: * * Same as free. * * RETURNS: * * Returns FREE_ERROR, FREE_NOERROR or void depending on whether STDC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -