/* This software was developed by Bruce Hendrickson and Robert Leland *
* at Sandia National Laboratories under US Department of Energy *
* contract DE-AC04-76DP00789 and is copyrighted by Sandia Corporation. */
#include <stdio.h>
#include <stdlib.h>
static int nmalloc = 0; /* number of calls to malloc */
static int nfree = 0; /* number of calls to free */
static int bytes_used = 0; /* current dynamic memory usage */
static int bytes_max = 0; /* largest dynamic memory usage */
static struct smalloc_debug_data {
int order; /* which smalloc call is it? */
unsigned size; /* size of malloc invocation */
double *ptr; /* memory location returned */
struct smalloc_debug_data *next; /* pointer to next element */
} *top = NULL;
/* Safe version of malloc. Does not initialize memory .*/
double *smalloc(n)
unsigned int n; /* number of bytes to be allocated */
{
extern FILE *Output_File; /* output file or null */
extern int DEBUG_MEMORY; /* use debug memory allocator? */
double *ptr; /* return value */
struct smalloc_debug_data *new; /* data structure for malloc data */
void bail();
nmalloc++;
if (n == 0) {
printf("ERROR: Non-positive argument to smalloc (%u).\n", n);
if (Output_File != NULL) {
fprintf(Output_File,
"ERROR: Non-positive argument to smalloc (%u).\n", n);
}
bail((char *) NULL, 1);
}
ptr = (double *) malloc(n);
if (ptr == NULL) {
printf("Program out of space while attempting to allocate %u. Sorry!\n", n);
if (Output_File != NULL) {
fprintf(Output_File,
"Program out of space while attempting to allocate %u. Sorry!\n", n);
}
bail((char *) NULL, 1);
}
if (DEBUG_MEMORY > 1) {
new = (struct smalloc_debug_data *)
malloc(sizeof(struct smalloc_debug_data));
if (new == NULL) {
printf("WARNING: No space for malloc_debug %u.\n", n);
if (Output_File != NULL) {
fprintf(Output_File,
"WARNING: No space for malloc_debug %u.\n", n);
}
return(ptr);
}
new->order = nmalloc;
new->size = n;
new->ptr = ptr;
new->next = top;
top = new;
bytes_used += n;
if (bytes_used > bytes_max) {
bytes_max = bytes_used;
}
}
if (DEBUG_MEMORY > 2) {
printf(" order=%d, size=%u, location=0x%lx\n", nmalloc, n, (long) ptr);
}
return (ptr);
}
/* Safe version of malloc. Does not initialize memory .*/
/* Returns instead of dying if it fails. */
double *smalloc_ret(n)
unsigned int n; /* number of bytes to be allocated */
{
extern FILE *Output_File; /* output file or null */
extern int DEBUG_MEMORY; /* use debug memory allocator? */
double *ptr; /* return value */
struct smalloc_debug_data *new; /* data structure for malloc data */
ptr = NULL;
if (n == 0) {
printf("ERROR: Non-positive argument to smalloc_ret (%u).\n", n);
if (Output_File != NULL) {
fprintf(Output_File,
"ERROR: Non-positive argument to smalloc_ret (%u).\n", n);
}
}
else {
nmalloc++;
ptr = (double *) malloc(n);
if (ptr == NULL) {
nmalloc--;
if (DEBUG_MEMORY > 0) {
printf("WARNING: No space in smalloc_ret while allocating %u.\n", n);
if (Output_File != NULL) {
fprintf(Output_File,
"WARNING: No space in smalloc_ret while allocating %u.\n", n);
}
}
}
else {
if (DEBUG_MEMORY > 1) {
new = (struct smalloc_debug_data *)
malloc(sizeof(struct smalloc_debug_data));
if (new == NULL) {
printf("WARNING: No space for malloc_debug %u.\n", n);
if (Output_File != NULL) {
fprintf(Output_File,
"WARNING: No space for malloc_debug %u.\n", n);
}
return(ptr);
}
new->order = nmalloc;
new->size = n;
new->ptr = ptr;
new->next = top;
top = new;
bytes_used += n;
if (bytes_used > bytes_max) {
bytes_max = bytes_used;
}
}
if (DEBUG_MEMORY > 2) {
printf(" order=%d, size=%u, location=0x%lx\n", nmalloc, n, (long) ptr);
}
}
}
return (ptr);
}
/* Safe version of realloc */
double *srealloc(ptr, n)
char *ptr; /* pointer to current location */
unsigned int n; /* desired size of new allocation */
{
extern FILE *Output_File; /* output file or null */
double *p; /* returned pointer */
extern int DEBUG_MEMORY; /* use debug memory allocator? */
struct smalloc_debug_data *dbptr; /* loops through debug list */
int sfree();
void bail();
if (ptr == NULL) {
if (n == 0) {
return ((double *) NULL);
}
else {
p = smalloc(n);
}
}
else {
if (n == 0) {
sfree((char *) ptr);
return ((double *) NULL);
}
else {
p = (double *) realloc((char *) ptr, n);
if (DEBUG_MEMORY > 1) {
for (dbptr = top; dbptr != NULL && (char *) dbptr->ptr != ptr; dbptr = dbptr->next) ;
if (dbptr == NULL) {
printf("Memory error: In srealloc, address not found in debug list (0x%lx)\n",
(long) ptr);
}
else {
dbptr->size = n;
dbptr->ptr = p;
bytes_used += n;
if (bytes_used > bytes_max) {
bytes_max = bytes_used;
}
}
}
}
}
if (p == NULL) {
printf("Program out of space while attempting to reallocate %u.\n", n);
if (Output_File != NULL) {
fprintf(Output_File,
"Program out of space while attempting to reallocate %u.\n", n);
}
bail((char *) NULL, 1);
}
return (p);
}
/* Safe version of realloc */
/* Returns instead of dying if it fails. */
double *srealloc_ret(ptr, n)
char *ptr; /* pointer to current location */
unsigned int n; /* desired size of new allocation */
{
extern FILE *Output_File; /* output file or null */
double *p; /* returned pointer */
extern int DEBUG_MEMORY; /* use debug memory allocator? */
struct smalloc_debug_data *dbptr; /* loops through debug list */
int sfree();
if (ptr == NULL) {
if (n == 0) {
return ((double *) NULL);
}
else {
p = smalloc(n);
}
}
else {
if (n == 0) {
sfree((char *) ptr);
return ((double *) NULL);
}
else {
p = (double *) realloc((char *) ptr, n);
if (DEBUG_MEMORY > 1) {
for (dbptr = top; dbptr != NULL && (char *) dbptr->ptr != ptr; dbptr = dbptr->next) ;
if (dbptr == NULL) {
printf("Memory error: In srealloc_ret, address not found in debug list (0x%lx)\n",
(long) ptr);
}
else {
dbptr->size = n;
dbptr->ptr = p;
bytes_used += n;
if (bytes_used > bytes_max) {
bytes_max = bytes_used;
}
}
}
}
}
if (p == NULL && DEBUG_MEMORY > 0) {
printf("WARNING: Program out of space while attempting to reallocate %u.\n", n);
if (Output_File != NULL) {
fprintf(Output_File,
"WARNING: Program out of space while attempting to reallocate %u.\n", n);
}
}
return (p);
}
/* Safe version of free. */
int sfree(ptr)
char *ptr;
{
extern FILE *Output_File; /* output file or null */
extern int DEBUG_MEMORY; /* use debug memory allocator? */
struct smalloc_debug_data *dbptr; /* loops through debug list */
struct smalloc_debug_data **prev; /* holds previous pointer */
if (DEBUG_MEMORY > 1) {
if (ptr != NULL) { /* search through debug list for it */
prev = ⊤
for (dbptr = top; dbptr != NULL && (char *) dbptr->ptr != ptr; dbptr = dbptr->next) {
prev = &(dbptr->next);
}
if (dbptr == NULL) {
printf("Memory error: In sfree, address not found in debug list (0x%lx)\n",
(long) ptr);
if (Output_File != NULL) {
printf("Memory error: In sfree, address not found in debug list (0x%lx)\n",
(long) ptr);
}
}
else {
*prev = dbptr->next;
bytes_used =- dbptr->size;
free((char *) dbptr);
}
}
}
if (ptr != NULL) {
nfree++;
free(ptr);
ptr = NULL;
}
return (0);
}
void smalloc_stats()
{
extern int DEBUG_MEMORY; /* use debug memory allocator? */
struct smalloc_debug_data *dbptr; /* loops through debug list */
if (DEBUG_MEMORY == 1) {
printf("Calls to smalloc = %d, Calls to sfree = %d\n", nmalloc, nfree);
}
if (DEBUG_MEMORY > 1) {
printf("Calls to smalloc = %d, Calls to sfree = %d, maximum bytes = %d\n",
nmalloc, nfree, bytes_max);
if (top != NULL) {
printf("Remaining allocations:\n");
for (dbptr = top; dbptr != NULL; dbptr = dbptr->next) {
printf(" order=%d, size=%u, location=0x%lx\n", dbptr->order,
dbptr->size, (long) dbptr->ptr);
}
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1