/* exarray.cpp Динамические массивы и указатели с автоматической проверкой индекса (сокращенный вариант). Функции распределения памяти. (C) Р.Н.Шакиров, ИМаш УрО PAH, 1998 - 2000 All Rights Reserved. */ #include <malloc.h> #include <string.h> #include <stdlib.h> #include <new.h> // Функция exmrealloc выделяет, удлиняет, // укорачивает и освобождает блоки памяти, // заполненные нулями. // При переполнении разрядной сетки индекса // вызывается функция abort(). // При нехватке памяти вызывается функция, // установленная по set_new_handler из // new.h, а если ее нет - то abort(). void exmrealloc (void **p, unsigned size, unsigned oldsize) { void *pp = *p; if (size) // Выделение памяти. { if (size > (~0u)-9) // Обход ошибки realloc(). abort(); while ((pp = realloc (*p, size)) == NULL) { // Вызов new_handler(). typedef void (*pvfunc) (void); pvfunc pvf = set_new_handler (NULL); set_new_handler (pvf); if (pvf) (*pvf)(); else abort(); } if (size > oldsize) memset // Обнуление. ((char*)pp + oldsize, 0, size - oldsize); } else // Оcвобождение памяти. { if (pp) { free (pp); pp = NULL; } } *p = pp; } // Функция excalcsize вычисляет размер блока // памяти в байтах, который должен быть не // меньше требуемого, для чего начальный // размер SIZE_MOD умножается на 2 и 1.5. // При переполнении выдается ~0u. // Для уменьшения фрагментации динамической // памяти учитывается размер системных данных // SIZE_SYS, добавляемых функцией realloc в // Borland C++ 3.1, 4.5. // Для оптимизации работы кэша L1 процесcоров // Pentuim SIZE_MOD задается как 64**n +/- 16. #define SIZE_MOD (112) #define SIZE_SYS (sizeof(int) * 2) unsigned excalcsize (unsigned size) { unsigned n = SIZE_MOD, k = 0; for (;; k = ~k, (k? (n <<= 1): (n += (n >> 1)))) { n -= SIZE_SYS; if (n >= size) break; n += SIZE_SYS; if ((int)n < 0) {n =~0u; break;} } return (n); } // Объект - константа, содержащий // нулевой указатель и нулевое значение. class { void* e; unsigned len; } __EXNULL;