cbec90699f
- creato il progetto in Visual Studio per compilare come libreria statica - modifiche al codice originale per integrarlo nelle nostre librerie.
277 lines
8.0 KiB
C++
277 lines
8.0 KiB
C++
/*****************************************************************************/
|
|
/* */
|
|
/* F I S T : Fast, Industrial-Strength Triangulation */
|
|
/* */
|
|
/*****************************************************************************/
|
|
/* */
|
|
/* (C) Martin Held */
|
|
/* (C) Universitaet Salzburg, Salzburg, Austria */
|
|
/* */
|
|
/* This code is not in the public domain. All rights reserved! Please make */
|
|
/* sure to read the full copyright statement contained in api_functions.cpp. */
|
|
/* */
|
|
/*****************************************************************************/
|
|
|
|
/* */
|
|
/* get standard libraries */
|
|
/* */
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
/* */
|
|
/* get my header files */
|
|
/* */
|
|
#include "fpkernel.h"
|
|
#include "martin.h"
|
|
#include "defs.h"
|
|
|
|
/* */
|
|
/* prototypes of functions provided in this file */
|
|
/* */
|
|
|
|
void *ReallocateArray(debug_memdef *mem, void *old_ptr, int number,
|
|
size_t size, const char var_name[]);
|
|
void FreeMemory(debug_memdef *mem, void **ptr, const char var_name[]);
|
|
boolean AllMemoryFreed(debug_memdef *mem);
|
|
unsigned long ReportMaxNumberBytes(debug_memdef *mem);
|
|
unsigned long ReportCurrNumberBytes(debug_memdef *mem);
|
|
|
|
#ifdef DEBUG_MEMORY
|
|
boolean IndexOutOfBounds(debug_memdef *mem, void *array_ptr, char var_name[],
|
|
size_t size, int index);
|
|
#endif /* DEBUG_MEMORY */
|
|
|
|
/* */
|
|
/* local stuff used for memory debugging */
|
|
/* */
|
|
#ifdef DEBUG_MEMORY
|
|
typedef enum { mem_freed, mem_allocated, mem_reallocated } memory_status;
|
|
void UpdateMemoryStatus(debug_memdef *mem, void *ptr, memory_status status,
|
|
size_t size, unsigned int high);
|
|
int SearchMemoryHistory(debug_memdef *mem, void *ptr);
|
|
void InitDebugMemDefaults(debug_memdef *mem);
|
|
#endif /* DEBUG_MEMORY */
|
|
|
|
|
|
#ifdef DEBUG_MEMORY
|
|
void InitDebugMemDefaults(debug_memdef *mem)
|
|
{
|
|
mem->curr_memory = 0;
|
|
mem->max_memory = 0;
|
|
mem->memory_dbg_cursor = 0;
|
|
}
|
|
#endif /* DEBUG_MEMORY */
|
|
|
|
void *ReallocateArray(debug_memdef *mem, void *old_ptr, int number,
|
|
size_t size, const char var_name[])
|
|
{
|
|
void *new_ptr;
|
|
|
|
if (old_ptr != (void*)NULL) {
|
|
#ifdef DEBUG_MEMORY
|
|
fprintf(stderr, "\nMDebug: ");
|
|
fprintf(stderr, "Reallocating %d elements of %d bytes for array `%s':",
|
|
number, (int)size, var_name);
|
|
fflush(stderr);
|
|
UpdateMemoryStatus(mem, old_ptr, mem_reallocated, size, number);
|
|
#endif /* DEBUG_MEMORY */
|
|
new_ptr = (void*) realloc((void*) old_ptr, number * size);
|
|
if (new_ptr == (void*)NULL) throw MEM_ALLOC_FAILED;
|
|
}
|
|
else {
|
|
#ifdef DEBUG_MEMORY
|
|
fprintf(stderr, "\nMDebug: ");
|
|
fprintf(stderr, "Allocating %d elements of %d bytes for array `%s':",
|
|
number, (int)size, var_name);
|
|
fflush(stderr);
|
|
#endif /* DEBUG_MEMORY */
|
|
new_ptr = (void*) calloc(number, size);
|
|
if (new_ptr == (void*)NULL) throw MEM_ALLOC_FAILED;
|
|
}
|
|
|
|
#ifdef DEBUG_MEMORY
|
|
fprintf(stderr, " done!\n");
|
|
fflush(stderr);
|
|
UpdateMemoryStatus(mem, new_ptr, mem_allocated, size, number);
|
|
#else
|
|
(void) mem;
|
|
(void) var_name;
|
|
#endif /* DEBUG_MEMORY */
|
|
|
|
return new_ptr;
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG_MEMORY
|
|
void UpdateMemoryStatus(debug_memdef *mem, void *ptr, memory_status status,
|
|
size_t size, unsigned int high)
|
|
{
|
|
int i;
|
|
|
|
switch(status) {
|
|
case(mem_allocated):
|
|
if (mem->memory_dbg_cursor < MAX_MEMORY_CURSOR) {
|
|
mem->memory_history[mem->memory_dbg_cursor].array_ptr = ptr;
|
|
mem->memory_history[mem->memory_dbg_cursor].size = size;
|
|
mem->memory_history[mem->memory_dbg_cursor].high = high;
|
|
++mem->memory_dbg_cursor;
|
|
mem->curr_memory += size * high;
|
|
if (mem->curr_memory > mem->max_memory)
|
|
mem->max_memory = mem->curr_memory;
|
|
}
|
|
else {
|
|
throw MEM_TRACKING_EXHAUSTED;
|
|
}
|
|
break;
|
|
case(mem_reallocated):
|
|
if (ptr != NULL) {
|
|
i = SearchMemoryHistory(mem, ptr);
|
|
if (i >= 0) {
|
|
if (mem->memory_history[i].size != size) {
|
|
throw MEM_REALLOC_MISMATCH;
|
|
}
|
|
mem->curr_memory -= size * mem->memory_history[i].high;
|
|
mem->memory_history[i].high = 0;
|
|
}
|
|
else {
|
|
throw MEM_TRACKING_MESSED_UP;
|
|
}
|
|
}
|
|
break;
|
|
case(mem_freed):
|
|
i = SearchMemoryHistory(mem, ptr);
|
|
if (i >= 0) {
|
|
mem->curr_memory -= mem->memory_history[i].size * mem->memory_history[i].high;
|
|
mem->memory_history[i].high = 0;
|
|
}
|
|
else {
|
|
throw MEM_TRACKING_MESSED_UP;
|
|
}
|
|
break;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
int SearchMemoryHistory(debug_memdef *mem, void *ptr)
|
|
{
|
|
int i;
|
|
|
|
i = mem->memory_dbg_cursor - 1;
|
|
|
|
while (i >= 0) {
|
|
if (mem->memory_history[i].array_ptr == ptr) return i;
|
|
--i;
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
#endif /* DEBUG_MEMORY */
|
|
|
|
|
|
|
|
unsigned long ReportMaxNumberBytes(debug_memdef *mem) {
|
|
#ifdef DEBUG_MEMORY
|
|
return mem->max_memory;
|
|
#else
|
|
(void) mem;
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
unsigned long ReportCurrNumberBytes(debug_memdef *mem) {
|
|
#ifdef DEBUG_MEMORY
|
|
return mem->curr_memory;
|
|
#else
|
|
(void) mem;
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
|
|
|
|
#ifdef DEBUG_MEMORY
|
|
boolean IndexOutOfBounds(debug_memdef *mem, void *array_ptr, char var_name[],
|
|
size_t size, int index)
|
|
{
|
|
int i;
|
|
|
|
i = SearchMemoryHistory(mem, array_ptr);
|
|
if (i >= 0) {
|
|
if (size != mem->memory_history[i].size) {
|
|
fprintf(stderr,
|
|
"*** Bytes per component of array `%s' do not match bytes ",
|
|
var_name);
|
|
fprintf(stderr, "specified! ***\n");
|
|
fprintf(stderr,
|
|
" Bytes per component: %d bytes; bytes specified: %d\n",
|
|
(int)mem->memory_history[i].size, (int)size);
|
|
fflush(stderr);
|
|
throw MEM_TYPE_MISMATCH;
|
|
}
|
|
return ((index < 0) || (index >= (int) mem->memory_history[i].high));
|
|
}
|
|
else {
|
|
fprintf(stderr, "*** IndexOutOfBounds: array `%s' has already been ",
|
|
var_name);
|
|
fprintf(stderr, "deallocated! ***\n");
|
|
fflush(stderr);
|
|
throw MEM_NULL_POINTER;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
#endif /* DEBUG_MEMORY */
|
|
|
|
|
|
|
|
|
|
void FreeMemory(debug_memdef *mem, void **ptr, const char var_name[])
|
|
{
|
|
if (*ptr == NULL) {
|
|
#ifdef DEBUG_MEMORY
|
|
fprintf(stderr, "FreeMemory() - array `%s' has already been freed!\n",
|
|
var_name);
|
|
fflush(stderr);
|
|
#endif
|
|
return;
|
|
}
|
|
|
|
#ifdef DEBUG_MEMORY
|
|
fprintf(stderr, "\nMDebug: `%s' has been freed\n", var_name);
|
|
fflush(stderr);
|
|
UpdateMemoryStatus(mem, *ptr, mem_freed, 0, 0);
|
|
#else
|
|
(void) mem;
|
|
(void) var_name;
|
|
#endif /* DEBUG_MEMORY */
|
|
|
|
free(*ptr);
|
|
*ptr = NULL;
|
|
|
|
return;
|
|
}
|
|
|
|
|
|
|
|
boolean AllMemoryFreed(debug_memdef *mem)
|
|
{
|
|
#ifdef DEBUG_MEMORY
|
|
int i;
|
|
|
|
for (i = 0; i < mem->memory_dbg_cursor; ++i) {
|
|
if (mem->memory_history[i].high != 0) return false;
|
|
}
|
|
#else
|
|
(void) mem;
|
|
#endif /* DEBUG_MEMORY */
|
|
|
|
return true;
|
|
}
|