📄 alloc.c
字号:
"Call to `%s' failed, due to FalseAllocFailPercentage.\n", mss_called_by_to_string(called_by, NULL)); mss_deinitialize_if_restarted(); mss_enable_threading(); return NULL; } } new_ptr = mss_alloc(size, called_by, filename, function, line); if (new_ptr == NULL) { if (size == 0) { mss_enable_threading(); mss_deinitialize_if_restarted(); return NULL; } mss_warn(MSS_WARN_IF_SHOW | MSS_WARN_SEPARATOR | MSS_WARN_NO_EXIT, "Out of memory in call to %s in %s (line %lu of %s).\n", method, function, line, filename); /* xrealloc() should exit upon allocation failure. */ if (called_by == MSS_BY_XREALLOC) { fprintf(stderr, "Out of memory in `%s'\n", method); mss_forced_deinitialize_if_restarted(); mss_enable_threading(); exit(EXIT_FAILURE); } } memcpy(new_ptr, ptr, size < node->size ? size : node->size); mss_log(MSS_LOG_MODE_NORMAL, "LOG", "%s (line %lu of %s) reallocated a block sized " MSS_PRINTF_SIZE_T " bytes at %p (%s) using `%s' " "into a block sized " MSS_PRINTF_SIZE_T " bytes at %p.\n", function, line, filename, (MSS_PTR_SIZE_T)node->size, ptr, node->label == NULL ? "no label" : node->label, method, (MSS_PTR_SIZE_T)size, new_ptr); mss_dealloc(ptr, called_by, filename, function, line); mss_deinitialize_if_restarted(); mss_enable_threading(); return new_ptr;}/* mss_free: This function will take care of the complete task of deallocating memory for the following functions; free(), xfree(), cfree(), delete and delete[]. TODO: Add check all on alloc */void mss_free(void *ptr, int called_by, const char *filename, const char *function, unsigned long line){ char method[32]; char dealloc_str[64]; MssNode *node; mss_disable_threading(); mss_check_if_initialized(); mss_called_by_to_string(called_by, method); mss_increase_mss_no_calls(called_by); /* Check if a warning about deallocating a NULL pointer should be issued. */ if (!ptr) { if (MSS_DO_ALWAYS_WARN_ON_NULL_DEALLOC) { mss_warn(MSS_WARN_IF_SHOW | MSS_WARN_SEPARATOR, "%s (line %lu of %s) tried to deallocate NULL pointer using `%s'.\n", function, line, filename, method); } mss_enable_threading(); mss_deinitialize_if_restarted(); return; } /* Try finding the node */ node = mss_find_node(ptr); if (node == NULL) { mss_warn(MSS_WARN_IF_SHOW | MSS_WARN_SEPARATOR, "%s (line %lu of %s) tried to deallocate a block at %p using `%s' that wasn't allocated.\n", function, line, filename, ptr, method); mss_enable_threading(); mss_deinitialize_if_restarted(); return; } /* Check that a memory block is deallocated using the appropriate function. */ switch (node->allocated_by) { case MSS_BY_NEW: strcpy(dealloc_str, "`delete'"); break; case MSS_BY_NEW_ARRAY: strcpy(dealloc_str, "`delete[]'"); break; case MSS_BY_MALLOC: case MSS_BY_XMALLOC: case MSS_BY_REALLOC: case MSS_BY_XREALLOC: case MSS_BY_CALLOC: case MSS_BY_STRDUP: strcpy(dealloc_str, "`free', `xfree' or `cfree'"); break; } if (called_by == MSS_BY_DELETE && node->allocated_by != MSS_BY_NEW) { mss_warn(MSS_WARN_IF_SHOW | MSS_WARN_SEPARATOR, "%s (line %lu of %s) deallocated a block sized " MSS_PRINTF_SIZE_T " bytes at %p (%s), " "using `%s' previously allocated by `%s' in %s (line %lu of %s). " "(Should be deallocated using %s).\n", function, line, filename, (MSS_PTR_SIZE_T)node->size, ptr, node->label == NULL ? "no label" : node->label, method, mss_called_by_to_string(node->allocated_by, NULL), node->function, node->line, node->filename, dealloc_str); } else if (called_by == MSS_BY_DELETE_ARRAY && node->allocated_by != MSS_BY_NEW_ARRAY) { mss_warn(MSS_WARN_IF_SHOW | MSS_WARN_SEPARATOR, "%s (line %lu of %s) deallocated a block sized " MSS_PRINTF_SIZE_T " bytes at %p (%s), " "using `%s' previously allocated by `%s' in %s (line %lu of %s). " "(Should be deallocated using %s).\n", function, line, filename, (MSS_PTR_SIZE_T)node->size, ptr, node->label == NULL ? "no label" : node->label, method, mss_called_by_to_string(node->allocated_by, NULL), node->function, node->line, node->filename, dealloc_str); } else if ((called_by == MSS_BY_FREE || called_by == MSS_BY_XFREE || called_by == MSS_BY_CFREE) && (node->allocated_by != MSS_BY_MALLOC && node->allocated_by != MSS_BY_REALLOC && node->allocated_by != MSS_BY_XMALLOC && node->allocated_by != MSS_BY_XREALLOC && node->allocated_by != MSS_BY_CALLOC && node->allocated_by != MSS_BY_STRDUP)) { mss_warn(MSS_WARN_IF_SHOW | MSS_WARN_SEPARATOR, "%s (line %lu of %s) deallocated a block sized " MSS_PRINTF_SIZE_T " bytes at %p (%s) " "using `%s', previously allocated by `%s' in %s (line %lu of %s). " "(Should be deallocated using %s).\n", function, line, filename, (MSS_PTR_SIZE_T)node->size, ptr, node->label == NULL ? "no label" : node->label, method, mss_called_by_to_string(node->allocated_by, NULL), node->function, node->line, node->filename, dealloc_str); } else { mss_log(MSS_LOG_MODE_NORMAL, "LOG", "%s (line %lu of %s) deallocated a block sized " MSS_PRINTF_SIZE_T " bytes at %p (%s) " "using `%s' previously allocated by `%s' in %s (line %lu of %s).\n", function, line, filename, (MSS_PTR_SIZE_T)node->size, ptr, node->label == NULL ? "no label" : node->label, method, mss_called_by_to_string(node->allocated_by, NULL), node->function, node->line, node->filename); } /* Fill memory with MSS_FILL_MEM_ON_DEALLOC_VALUE if MSS_DO_FILL_MEM_ON_DEALLOC was set to true. */ if (MSS_DO_FILL_MEM_ON_DEALLOC) { memset(ptr, MSS_FILL_MEM_ON_DEALLOC_VALUE, node->size); } mss_dealloc(ptr, called_by, filename, function, line); mss_deinitialize_if_restarted(); mss_enable_threading();}/* mss_malloc: This function takes care of the complete task of allocating memory, for the following functions: malloc, calloc, xmalloc, new, new[]. the memory allocating part of strdup. It also handles requests from realloc and xrealloc if NULL was passed as the pointer to these functions. */void *mss_malloc(size_t s, int called_by, const char *filename, const char *function, unsigned long line){ void *ptr; char method[32]; mss_disable_threading(); mss_check_if_initialized(); mss_called_by_to_string(called_by, method); mss_increase_mss_no_calls(called_by); if (called_by == MSS_BY_MALLOC || called_by == MSS_BY_CALLOC || called_by == MSS_BY_STRDUP) { if (mss_false_fail()) { mss_warn(MSS_WARN_SEPARATOR | MSS_WARN_NO_EXIT, "Call to `%s' failed, due to FalseAllocFailPercentage.\n", mss_called_by_to_string(called_by, NULL)); mss_deinitialize_if_restarted(); mss_enable_threading(); return NULL; } } ptr = mss_alloc(s, called_by, filename, function, line); if (ptr == NULL) { if (s == 0) { mss_enable_threading(); mss_deinitialize_if_restarted(); return NULL; } mss_warn(MSS_WARN_IF_SHOW | MSS_WARN_SEPARATOR | MSS_WARN_NO_EXIT, "Out of memory in call to %s in %s (line %lu of %s).\n", method, function, line, filename); /* xmalloc() should exit upon allocation failure. */ if (called_by == MSS_BY_XMALLOC || called_by == MSS_BY_NEW || called_by == MSS_BY_NEW_ARRAY || called_by == MSS_BY_XREALLOC) { /* `new' must not return NULL */ fprintf(stderr, "Out of memory in `%s'\n", method); mss_forced_deinitialize_if_restarted(); mss_enable_threading(); exit(EXIT_FAILURE); } mss_forced_deinitialize_if_restarted(); mss_enable_threading(); return NULL; } if (called_by == MSS_BY_CALLOC) { memset(ptr, 0, s); } else if (MSS_DO_FILL_MEM_ON_ALLOC && called_by != MSS_BY_STRDUP) { memset(ptr, MSS_FILL_MEM_ON_ALLOC_VALUE, s); } mss_log(MSS_LOG_MODE_NORMAL, "LOG", "%s (line %lu of %s) allocated " MSS_PRINTF_SIZE_T " bytes at %p using `%s'.\n", function, line, filename, (MSS_PTR_SIZE_T)s, ptr, method); mss_deinitialize_if_restarted(); mss_enable_threading(); return ptr;}/* mss_increase_mss_no_calls: This function will increase the mss_no.XXX.calls for the appropriate method, based upon CALLED_BY passed to the function. */void mss_increase_mss_no_calls(int called_by){ switch (called_by) { case MSS_BY_NEW: mss_no.news.calls++; break; case MSS_BY_NEW_ARRAY: mss_no.new_arrays.calls++; break; case MSS_BY_DELETE: mss_no.deletes.calls++; break; case MSS_BY_DELETE_ARRAY: mss_no.delete_arrays.calls++; break; case MSS_BY_MALLOC: mss_no.mallocs.calls++; break; case MSS_BY_REALLOC: mss_no.reallocs.calls++; break; case MSS_BY_CALLOC: mss_no.callocs.calls++; break; case MSS_BY_FREE: mss_no.frees.calls++; break; case MSS_BY_XMALLOC: mss_no.xmallocs.calls++; break; case MSS_BY_XREALLOC: mss_no.xreallocs.calls++; break; case MSS_BY_XFREE: mss_no.xfrees.calls++; break; case MSS_BY_CFREE: mss_no.cfrees.calls++; break; case MSS_BY_STRDUP: mss_no.strdups.calls++; break; default:#ifdef MSS_DEBUG fprintf(stderr, "mss_increase_mss_no_calls() called with an unknown called_by value (was %i).", called_by);#endif break; }}/* mss_dealloc: This function will deallocate the block starting at `ptr' if it exists, and remove node from `mss_list'. It returns a non-zero value upon success, and zero (false) otherwise. (If `ptr' doesn't exist it will fail and return zero). It also updates the mss_num_deletes family of variables, and updates mss_used_mem. */int mss_dealloc(void *ptr, int called_by, const char *filename, const char *function, unsigned long line){ MssNode *node; int result; mss_disable_threading(); node = mss_find_node(ptr); if (node == NULL) { mss_enable_threading(); return 0; } mss_num_of_blocks--; mss_used_mem -= node->size; switch (called_by) { case MSS_BY_DELETE: mss_no.deletes.successes++; break; case MSS_BY_DELETE_ARRAY: mss_no.delete_arrays.successes++; break; case MSS_BY_FREE: mss_no.frees.successes++; break; case MSS_BY_XFREE: mss_no.xfrees.successes++; break; case MSS_BY_CFREE: mss_no.cfrees.successes++; break; case MSS_BY_REALLOC: case MSS_BY_XREALLOC: break; default:#ifdef MSS_DEBUG fprintf(stderr, "mss_dealloc() called with an unknown `called_by', was %i\n", called_by);#endif break; } if (MSS_DO_CHECK_ALL_ON_ALLOC) { mss_check_all_blocks_on_alloc("Check all blocks being performed upon deallocation.\n", filename, function, line); node = mss_find_node(ptr); } else if (MSS_DO_CHECK_ON_DEALLOC) { result = mss_check_node(node); if (result != MSS_CHECK_NODE_OK) { mss_log(MSS_LOG_MODE_ALWAYS | MSS_LOG_MODE_NO_EXTRA_NEWLINE, NULL, mss_separator); mss_log_check_node_warnings(node, result, filename, function, line); mss_log(MSS_LOG_MODE_ALWAYS, NULL, mss_separator); } } if (MSS_DO_WATCH_LIMITS) { node->ptr = (void *)((MSS_PTR_SIZE_T)node->ptr - MSS_WATCH_LIMITS_SIZE); } free(node->ptr); dcflist_remove(&mss_list); mss_enable_threading(); return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -