void * NUMmatrix (long elementSize, long row1, long row2, long col1, long col2) { try { int64 numberOfRows = row2 - row1 + 1; int64 numberOfColumns = col2 - col1 + 1; int64 numberOfCells = numberOfRows * numberOfColumns; /* * Allocate room for the row pointers. */ char **result; Melder_assert (sizeof (char) == 1); // true by definition for (;;) { result = reinterpret_cast <char **> (_Melder_malloc_f (numberOfRows * sizeof (char *))); // assume that all pointers have the same size result -= row1; if (result) break; // this will normally succeed at the first try (void) Melder_realloc_f (result + row1, 1); // make "sure" that the second try will succeed } /* * Allocate room for the cells. * The first row pointer points to below the first cell. */ for (;;) { try { result [row1] = reinterpret_cast <char *> (_Melder_calloc (numberOfCells, elementSize)); } catch (MelderError) { result += row1; Melder_free (result); // free the row pointers throw MelderError (); } if ((result [row1] -= col1 * elementSize) != nullptr) break; // this will normally succeed at the first try (void) Melder_realloc_f (result [row1] + col1 * elementSize, 1); // make "sure" that the second try will succeed } int64 columnSize = numberOfColumns * elementSize; for (long irow = row1 + 1; irow <= row2; irow ++) result [irow] = result [irow - 1] + columnSize; theTotalNumberOfArrays += 1; return result; } catch (MelderError) { Melder_throw (U"Matrix of elements not created."); } }
void * NUMvector (long elementSize, long lo, long hi) { try { if (hi < lo) return nullptr; // not an error char *result; Melder_assert (sizeof (char) == 1); // some say that this is true by definition for (;;) { // not very infinite: 99.999 % of the time once, 0.001 % twice result = reinterpret_cast<char*> (_Melder_calloc (hi - lo + 1, elementSize)); if (result -= lo * elementSize) break; // this will normally succeed at the first try (void) Melder_realloc_f (result + lo * elementSize, 1); // make "sure" that the second try will succeed (not *very* sure, because realloc might move memory even if it shrinks) } theTotalNumberOfArrays += 1; return result; } catch (MelderError) { Melder_throw (U"Vector of elements not created."); } }
void NUMvector_append (long elementSize, void **v, long lo, long *hi) { try { char *result; if (! *v) { result = reinterpret_cast <char *> (NUMvector (elementSize, lo, lo)); *hi = lo; } else { long offset = lo * elementSize; for (;;) { // not very infinite: 99.999 % of the time once, 0.001 % twice result = reinterpret_cast <char *> (Melder_realloc ((char *) *v + offset, (*hi - lo + 2) * elementSize)); if ((result -= offset) != nullptr) break; // this will normally succeed at the first try (void) Melder_realloc_f (result + offset, 1); // make "sure" that the second try will succeed } (*hi) ++; memset (result + *hi * elementSize, 0, elementSize); // initialize the new element to zeroes } *v = result; } catch (MelderError) { Melder_throw (U"Vector: element not appended."); } }
static void NUMvector_extendNumberOfElements (long elementSize, void **v, long lo, long *hi, long extraDemand) { try { char *result; if (! *v) { long newhi = lo + extraDemand - 1; result = reinterpret_cast <char *> (NUMvector (elementSize, lo, newhi)); *hi = newhi; } else { long offset = lo * elementSize; for (;;) { // not very infinite: 99.999 % of the time once, 0.001 % twice result = reinterpret_cast <char *> (Melder_realloc ((char *) *v + offset, (*hi - lo + 1 + extraDemand) * elementSize)); if ((result -= offset)) break; // this will normally succeed at the first try (void) Melder_realloc_f (result + offset, 1); // ??make "sure" that the second try will succeed } (*hi) += extraDemand; memset (result + *hi * elementSize, 0, elementSize); // initialize the new elements to zeroes } *v = result; } catch (MelderError) { Melder_throw (U"Vector: size not extended."); } }