SDDS ToolKit Programs and Libraries for C and Python
Loading...
Searching...
No Matches
array.c File Reference

Detailed Description

Implementation of dynamic 2D arrays and memory management functions.

This file contains functions for allocating, resizing, and freeing 2D arrays, as well as custom memory allocation functions with tracking capabilities.

License
This file is distributed under the terms of the Software License Agreement found in the file LICENSE included with this distribution.
Author
M. Borland, C. Saunders, R. Soliday, H. Shang

Definition in file array.c.

#include "mdb.h"
#include "mdb_thread.h"

Go to the source code of this file.

Functions

void keep_alloc_record (char *filename)
 Keeps a record of memory allocations by opening tracking files.
 
void * tmalloc (uint64_t size_of_block)
 Allocates a memory block of the specified size with zero initialization.
 
void ** zarray_2d (uint64_t size, uint64_t n1, uint64_t n2)
 Allocates a 2D array with specified dimensions.
 
void ** resize_zarray_2d (uint64_t size, uint64_t old_n1, uint64_t old_n2, void **array, uint64_t n1, uint64_t n2)
 Resizes an existing 2D array to new dimensions.
 
int free_zarray_2d (void **array, uint64_t n1, uint64_t n2)
 Frees a 2D array and its associated memory.
 
void * trealloc (void *old_ptr, uint64_t size_of_block)
 Reallocates a memory block to a new size.
 
void zero_memory (void *mem, uint64_t n_bytes)
 Sets a block of memory to zero.
 
int tfree (void *ptr)
 Frees a memory block and records the deallocation if tracking is enabled.
 
void * array_1d (uint64_t size, uint64_t lower_index, uint64_t upper_index)
 Allocates a 1D array with specified lower and upper indices.
 
void ** array_2d (uint64_t size, uint64_t lower1, uint64_t upper1, uint64_t lower2, uint64_t upper2)
 Allocates a 2D array with specified lower and upper indices for both dimensions.
 
int free_array_1d (void *array, uint64_t size, uint64_t lower_index, uint64_t upper_index)
 Frees a 1D array that was previously allocated.
 
int free_array_2d (void **array, uint64_t size, uint64_t lower1, uint64_t upper1, uint64_t lower2, uint64_t upper2)
 Frees a 2D array and its associated memory.
 
void ** czarray_2d (const uint64_t size, const uint64_t n1, const uint64_t n2)
 Allocates a contiguous 2D array with zero-based indexing.
 
void ** resize_czarray_2d (void **data, uint64_t size, uint64_t n1, uint64_t n2)
 Resizes a contiguous 2D array to new dimensions.
 
int free_czarray_2d (void **array, uint64_t n1, uint64_t n2)
 Frees a contiguous 2D array and its associated memory.
 

Function Documentation

◆ array_1d()

void * array_1d ( uint64_t size,
uint64_t lower_index,
uint64_t upper_index )

Allocates a 1D array with specified lower and upper indices.

Allocates memory for a 1D array and adjusts the pointer based on the lower index to allow negative indexing if necessary.

Parameters
sizeThe size of each element in the array.
lower_indexThe lower index of the array.
upper_indexThe upper index of the array.
Returns
Pointer to the allocated 1D array.

Definition at line 268 of file array.c.

268 {
269 char *ptr;
270
271 if (!(ptr = tmalloc((uint64_t)size * (upper_index - lower_index + 1))))
272 bomb("unable to allocate array (array_1d)", NULL);
273 ptr -= lower_index * size;
274 return ((void *)ptr);
275}
void * tmalloc(uint64_t size_of_block)
Allocates a memory block of the specified size with zero initialization.
Definition array.c:65
void bomb(char *error, char *usage)
Reports error messages to the terminal and aborts the program.
Definition bomb.c:26

◆ array_2d()

void ** array_2d ( uint64_t size,
uint64_t lower1,
uint64_t upper1,
uint64_t lower2,
uint64_t upper2 )

Allocates a 2D array with specified lower and upper indices for both dimensions.

Allocates memory for a 2D array of pointers, where each row is a 1D array. Adjusts pointers based on lower indices to allow for flexible indexing ranges.

Parameters
sizeThe size of each element in the array.
lower1The lower index for the first dimension (rows).
upper1The upper index for the first dimension (rows).
lower2The lower index for the second dimension (columns).
upper2The upper index for the second dimension (columns).
Returns
Pointer to the allocated 2D array.

Definition at line 290 of file array.c.

293{
294 register uint64_t i, n1, n2;
295 char **ptr;
296
297 if (!(ptr = tmalloc((uint64_t)sizeof(*ptr) *(n1 = upper1 - lower1 + 1))))
298 bomb("unable to allocate array (array_2d)", NULL);
299
300 n2 = upper2 - lower2 + 1;
301 for (i = 0; i < n1; i++) {
302 if (!(ptr[i] = tmalloc((uint64_t)size * n2)))
303 bomb("unable to allocate array (array_2d)", NULL);
304 ptr[i] -= lower2 * size;
305 }
306
307 return ((void **)(ptr - lower1));
308}

◆ czarray_2d()

void ** czarray_2d ( const uint64_t size,
const uint64_t n1,
const uint64_t n2 )

Allocates a contiguous 2D array with zero-based indexing.

Allocates a single contiguous block of memory for a 2D array and sets up row pointers accordingly.

Parameters
sizeThe size of each element in the array.
n1The number of rows.
n2The number of columns.
Returns
Pointer to the allocated contiguous 2D array.

Definition at line 373 of file array.c.

373 {
374 char **ptr0;
375 char *buffer;
376 uint64_t i;
377
378 ptr0 = (char **)tmalloc((uint64_t)(sizeof(*ptr0) * n1));
379 buffer = (char *)tmalloc((uint64_t)(sizeof(*buffer) * size * n1 * n2));
380 for (i = 0; i < n1; i++)
381 ptr0[i] = buffer + i * size * n2;
382 return ((void **)ptr0);
383}

◆ free_array_1d()

int free_array_1d ( void * array,
uint64_t size,
uint64_t lower_index,
uint64_t upper_index )

Frees a 1D array that was previously allocated.

Adjusts the pointer based on the lower index and frees the allocated memory.

Parameters
arrayPointer to the 1D array to free.
sizeThe size of each element in the array.
lower_indexThe lower index of the array.
upper_indexThe upper index of the array.
Returns
Status of the free operation (1 if successful, 0 otherwise).

Definition at line 321 of file array.c.

322 {
323 if (!array)
324 return (0);
325 free((char *)array + size * lower_index);
326 return (1);
327}

◆ free_array_2d()

int free_array_2d ( void ** array,
uint64_t size,
uint64_t lower1,
uint64_t upper1,
uint64_t lower2,
uint64_t upper2 )

Frees a 2D array and its associated memory.

Adjusts the pointer based on the lower indices and frees each row followed by the array of pointers.

Parameters
arrayPointer to the 2D array to free.
sizeThe size of each element in the array.
lower1The lower index for the first dimension (rows).
upper1The upper index for the first dimension (rows).
lower2The lower index for the second dimension (columns).
upper2The upper index for the second dimension (columns).
Returns
Status of the free operation (1 if successful, 0 otherwise).

Definition at line 342 of file array.c.

345{
346 uint64_t i, n1;
347 char *ptr;
348
349 if (!array)
350 return (0);
351
352 n1 = upper1 - lower1 + 1;
353 array += lower1;
354 for (i = 0; i < n1; i++) {
355 if ((ptr = (char *)array[i] + size * lower2))
356 free(ptr);
357 }
358
359 free(array);
360 return (1);
361}

◆ free_czarray_2d()

int free_czarray_2d ( void ** array,
uint64_t n1,
uint64_t n2 )

Frees a contiguous 2D array and its associated memory.

Frees the contiguous memory block holding the array elements and the array of row pointers.

Parameters
arrayPointer to the contiguous 2D array to free.
n1The number of rows in the array.
n2The number of columns in the array.
Returns
Status of the free operation (always returns 0).

Definition at line 420 of file array.c.

420 {
421 free(*array);
422 free(array);
423 return 0;
424}

◆ free_zarray_2d()

int free_zarray_2d ( void ** array,
uint64_t n1,
uint64_t n2 )

Frees a 2D array and its associated memory.

Frees each row of the 2D array and then frees the array of pointers itself.

Parameters
arrayPointer to the 2D array to free.
n1The number of rows in the array.
n2The number of columns in the array.
Returns
Status of the free operation (1 if successful, 0 otherwise).

Definition at line 164 of file array.c.

164 {
165 void *ptr0;
166
167 if (!(ptr0 = array))
168 return (0);
169 while (n1--) {
170 if (*array) {
171 tfree(*array);
172 *array = NULL;
173 } else
174 return (0);
175 array++;
176 }
177 return (tfree(ptr0));
178}
int tfree(void *ptr)
Frees a memory block and records the deallocation if tracking is enabled.
Definition array.c:243

◆ keep_alloc_record()

void keep_alloc_record ( char * filename)

Keeps a record of memory allocations by opening tracking files.

Opens tracking files for memory allocation, reallocation, and freeing based on the provided filename. If tracking files are already open, they are closed before reopening.

Parameters
filenameThe base name for the tracking files.

Definition at line 37 of file array.c.

37 {
38 char s[100];
39
40 mdb_thread_lock(&alloc_record_lock);
41 if (fp_tmalloc)
42 fclose(fp_tmalloc);
43 if (fp_trealloc)
44 fclose(fp_trealloc);
45 if (fp_tfree)
46 fclose(fp_tfree);
47 sprintf(s, "%s.tmalloc", filename);
48 fp_tmalloc = fopen_e(s, "w", 0);
49 sprintf(s, "%s.trealloc", filename);
50 fp_trealloc = fopen_e(s, "w", 0);
51 sprintf(s, "%s.tfree", filename);
52 fp_tfree = fopen_e(s, "w", 0);
53 mdb_thread_unlock(&alloc_record_lock);
54}
FILE * fopen_e(char *file, char *open_mode, long mode)
Opens a file with error checking, messages, and aborts.
Definition fopen_e.c:30

◆ resize_czarray_2d()

void ** resize_czarray_2d ( void ** data,
uint64_t size,
uint64_t n1,
uint64_t n2 )

Resizes a contiguous 2D array to new dimensions.

Resizes both the array of row pointers and the contiguous memory block holding the array elements.

Parameters
dataPointer to the original contiguous 2D array.
sizeThe size of each element in the array.
n1The new number of rows.
n2The new number of columns.
Returns
Pointer to the resized contiguous 2D array.

Definition at line 396 of file array.c.

396 {
397 char **ptr0;
398 char *buffer;
399 uint64_t i;
400
401 if (!data)
402 return czarray_2d(size, n1, n2);
403 buffer = (char *)trealloc(*data, (uint64_t)(sizeof(char) * size * n1 * n2));
404 ptr0 = (char **)trealloc(data, (uint64_t)(sizeof(char *) * n1));
405 for (i = 0; i < n1; i++)
406 ptr0[i] = buffer + i * size * n2;
407 return ((void **)ptr0);
408}
void * trealloc(void *old_ptr, uint64_t size_of_block)
Reallocates a memory block to a new size.
Definition array.c:190
void ** czarray_2d(const uint64_t size, const uint64_t n1, const uint64_t n2)
Allocates a contiguous 2D array with zero-based indexing.
Definition array.c:373

◆ resize_zarray_2d()

void ** resize_zarray_2d ( uint64_t size,
uint64_t old_n1,
uint64_t old_n2,
void ** array,
uint64_t n1,
uint64_t n2 )

Resizes an existing 2D array to new dimensions.

Resizes the array of pointers if the number of rows (n1) increases. Additionally, resizes each row to accommodate more columns (n2) if needed. If resizing fails, the function aborts the program.

Parameters
sizeThe size of each element in the array.
old_n1The original number of rows.
old_n2The original number of columns.
arrayPointer to the original 2D array.
n1The new number of rows.
n2The new number of columns.
Returns
Pointer to the resized 2D array.

Definition at line 126 of file array.c.

127 {
128 void **ptr;
129
130 if (n1 > old_n1) {
131 /* increase length of array of pointers */
132 if (!(array = (void **)trealloc((void *)array,
133 (uint64_t)(sizeof(*array) * n1))))
134 bomb("memory allocation failuire in resize_zarray_2d()", NULL);
135 /* allocate memory for new pointed-to objects */
136 ptr = array + n1;
137 while (n1-- != old_n1)
138 *--ptr = (void *)tmalloc(size * n2);
139 }
140
141 if (n2 > old_n2) {
142 /* increase size of old pointed-to objects */
143 ptr = array;
144 while (old_n1--) {
145 if (!(*ptr = (void *)trealloc((void *)*ptr, (uint64_t)(size * n2))))
146 bomb("memory allocation failure in resize_zarray_2d()", NULL);
147 ptr++;
148 }
149 }
150
151 return (array);
152}

◆ tfree()

int tfree ( void * ptr)

Frees a memory block and records the deallocation if tracking is enabled.

Frees the specified memory block and logs the deallocation if tracking is active.

Parameters
ptrPointer to the memory block to free.
Returns
Status of the free operation (1 if successful, 0 otherwise).

Definition at line 243 of file array.c.

243 {
244 mdb_thread_lock(&alloc_record_lock);
245 if (fp_tfree) {
246 fprintf(fp_tfree, "%"PRIx64"\n", (uint64_t)ptr);
247 fflush(fp_tfree);
248 }
249 mdb_thread_unlock(&alloc_record_lock);
250 if (ptr) {
251 free(ptr);
252 return (1);
253 }
254 return (0);
255}

◆ tmalloc()

void * tmalloc ( uint64_t size_of_block)

Allocates a memory block of the specified size with zero initialization.

Uses calloc to allocate memory and initializes it to zero. Tracks the allocation if tracking is enabled. If the allocation fails, the function prints an error message and aborts the program.

Parameters
size_of_blockThe size of the memory block to allocate in bytes.
Returns
Pointer to the allocated memory block.

Definition at line 65 of file array.c.

65 {
66 void *ptr;
67
68 if (size_of_block <= 0)
69 size_of_block = 4;
70
71 /* even though the function is tMalloc, I use calloc to get memory filled
72 * with zeros
73 */
74 if (!(ptr = calloc(size_of_block, 1))) {
75 printf("error: memory allocation failure--%"PRIu64" Bytes requested.\n",
76 size_of_block);
77 mdb_thread_lock(&alloc_record_lock);
78 printf("tmalloc() has allocated %"PRIu64" bytes previously\n", tmalloc_total_bytes);
79 mdb_thread_unlock(&alloc_record_lock);
80 abort();
81 }
82 mdb_thread_lock(&alloc_record_lock);
83 if (fp_tmalloc) {
84 fprintf(fp_tmalloc, "%"PRIx64" %"PRIu64"\n", (uint64_t)ptr, size_of_block);
85 fflush(fp_tmalloc);
86 }
87 tmalloc_total_bytes += size_of_block;
88 mdb_thread_unlock(&alloc_record_lock);
89 return (ptr);
90}

◆ trealloc()

void * trealloc ( void * old_ptr,
uint64_t size_of_block )

Reallocates a memory block to a new size.

Uses realloc to resize the memory block. Tracks the reallocation if tracking is enabled. If the reallocation fails, the function prints an error message and aborts the program.

Parameters
old_ptrPointer to the original memory block.
size_of_blockThe new size for the memory block in bytes.
Returns
Pointer to the reallocated memory block.

Definition at line 190 of file array.c.

190 {
191 void *ptr;
192
193 if (size_of_block <= 0)
194 size_of_block = 4;
195
196 if (!old_ptr)
197 return (tmalloc(size_of_block));
198 uint64_t oldaddr = (uint64_t)old_ptr;
199 if (!(ptr = realloc(old_ptr, (uint64_t)(size_of_block)))) {
200 printf("error: memory reallocation failure--%"PRIu64" bytes requested.\n",
201 size_of_block);
202 mdb_thread_lock(&alloc_record_lock);
203 printf("trealloc() has reallocated %"PRIu64" bytes previously\n", trealloc_total_bytes);
204 mdb_thread_unlock(&alloc_record_lock);
205 abort();
206 }
207 mdb_thread_lock(&alloc_record_lock);
208 if (fp_trealloc) {
209 fprintf(fp_trealloc, "d:%"PRIx64"\na:%"PRIx64" %"PRIu64"\n", oldaddr,
210 (uint64_t)ptr, size_of_block);
211 fflush(fp_trealloc);
212 }
213 trealloc_total_bytes += size_of_block;
214 mdb_thread_unlock(&alloc_record_lock);
215 return (ptr);
216}

◆ zarray_2d()

void ** zarray_2d ( uint64_t size,
uint64_t n1,
uint64_t n2 )

Allocates a 2D array with specified dimensions.

Allocates memory for a 2D array where each row is a contiguous block of memory. Initializes each row to zero.

Parameters
sizeThe size of each element in the array.
n1The number of rows.
n2The number of columns.
Returns
Pointer to the allocated 2D array.

Definition at line 102 of file array.c.

102 {
103 void **ptr1, **ptr0;
104
105 ptr0 = ptr1 = (void **)tmalloc((uint64_t)(sizeof(*ptr0) * n1));
106 while (n1--)
107 *ptr1++ = (void *)tmalloc((uint64_t)(size * n2));
108 return (ptr0);
109}

◆ zero_memory()

void zero_memory ( void * mem,
uint64_t n_bytes )

Sets a block of memory to zero.

Iterates through the specified memory block and sets each byte to zero.

Parameters
memPointer to the memory block.
n_bytesThe number of bytes to set to zero.

Definition at line 226 of file array.c.

226 {
227 char *cmem;
228
229 if (!(cmem = mem))
230 return;
231 while (n_bytes--)
232 *cmem++ = 0;
233}