/** * Frees memory and adjusts pointers. * * @param pointer pointer to delete * @param addr pointer to the caller * @param is_array flag indicating whether it is invoked by a * <code>delete[]</code> call */ void __debug_new_recorder::free_pointer(void* pointer, void* addr, bool is_array) { if (pointer == NULL) { return; } new_ptr_list_t* ptr = (new_ptr_list_t*)((char*)pointer - ALIGNED_LIST_ITEM_SIZE); if (ptr->magic != MAGIC) { { fast_mutex_autolock lock(new_output_lock); const char * msg_out = "[QxOrm] delete%s: invalid pointer %p"; Q_UNUSED(msg_out); qDebug(msg_out, (is_array ? "[]" : ""), pointer); } check_mem_corruption(); fflush(new_output_fp); _DEBUG_NEW_ERROR_ACTION; } if (is_array != ptr->is_array) { const char * msg; if (is_array) { msg = "[QxOrm] delete[] after new"; } else { msg = "[QxOrm] delete after new[]"; } fast_mutex_autolock lock(new_output_lock); const char * msg_out_file = "[QxOrm] %s: pointer %p (size %u)\n\tat %p\n\toriginally allocated at %s:%d"; Q_UNUSED(msg_out_file); const char * msg_out_no_file = "[QxOrm] %s: pointer %p (size %u)\n\tat %p\n\toriginally allocated at <Unknown>"; Q_UNUSED(msg_out_no_file); if (ptr->line != 0) { qDebug(msg_out_file, msg, ((char*)ptr + ALIGNED_LIST_ITEM_SIZE), ptr->size, addr, ptr->file, ptr->line); } #if (! _QX_MEM_LEAK_ONLY_KNOWN_SRC_FILE) else { qDebug(msg_out_no_file, msg, ((char*)ptr + ALIGNED_LIST_ITEM_SIZE), ptr->size, addr); } #endif // (! _QX_MEM_LEAK_ONLY_KNOWN_SRC_FILE) fflush(new_output_fp); _DEBUG_NEW_ERROR_ACTION; } #if _DEBUG_NEW_TAILCHECK if (!check_tail(ptr)) { check_mem_corruption(); fflush(new_output_fp); _DEBUG_NEW_ERROR_ACTION; } #endif { fast_mutex_autolock lock(new_ptr_lock); total_mem_alloc -= ptr->size; ptr->magic = 0; ptr->prev->next = ptr->next; ptr->next->prev = ptr->prev; } if (new_verbose_flag) { fast_mutex_autolock lock(new_output_lock); const char * msg_out = "[QxOrm] delete%s: freed %p (size %u, %u bytes still allocated)"; Q_UNUSED(msg_out); qDebug(msg_out, (is_array ? "[]" : ""), ((char*)ptr + ALIGNED_LIST_ITEM_SIZE), ptr->size, total_mem_alloc); } free(ptr); return; }
/** * Frees memory and adjusts pointers. * * @param pointer pointer to the previously allocated memory * @param addr pointer to the caller * @param is_array flag indicating whether it is invoked by a * <code>delete[]</code> call */ static void free_pointer(void* pointer, void* addr, bool is_array) { if (pointer == NULL) return; new_ptr_list_t* ptr = (new_ptr_list_t*)((char*)pointer - ALIGNED_LIST_ITEM_SIZE); if (ptr->magic != MAGIC) { { fast_mutex_autolock lock(new_output_lock); fprintf(new_output_fp, "delete%s: invalid pointer %p (", is_array ? "[]" : "", pointer); print_position(addr, 0); fprintf(new_output_fp, ")\n"); } check_mem_corruption(); fflush(new_output_fp); _DEBUG_NEW_ERROR_ACTION; } if (is_array != ptr->is_array) { const char* msg; if (is_array) msg = "delete[] after new"; else msg = "delete after new[]"; fast_mutex_autolock lock(new_output_lock); fprintf(new_output_fp, "%s: pointer %p (size %lu)\n\tat ", msg, (char*)ptr + ALIGNED_LIST_ITEM_SIZE, (unsigned long)ptr->size); print_position(addr, 0); fprintf(new_output_fp, "\n\toriginally allocated at "); if (ptr->line != 0) print_position(ptr->file, ptr->line); else print_position(ptr->addr, ptr->line); fprintf(new_output_fp, "\n"); fflush(new_output_fp); _DEBUG_NEW_ERROR_ACTION; } #if _DEBUG_NEW_TAILCHECK if (!check_tail(ptr)) { check_mem_corruption(); fflush(new_output_fp); _DEBUG_NEW_ERROR_ACTION; } #endif { fast_mutex_autolock lock(new_ptr_lock); total_mem_alloc -= ptr->size; ptr->magic = 0; ptr->prev->next = ptr->next; ptr->next->prev = ptr->prev; } if (new_verbose_flag) { fast_mutex_autolock lock(new_output_lock); fprintf(new_output_fp, "delete%s: freed %p (size %lu, %lu bytes still allocated)\n", is_array ? "[]" : "", (char*)ptr + ALIGNED_LIST_ITEM_SIZE, (unsigned long)ptr->size, (unsigned long)total_mem_alloc); } free(ptr); return; }