http://prostoserver.com/rus/
Страница Игоря Разина
Программы Примеры Книги
Динамический массив

Исходный текст

Теория: Дж. Рихтер, "Windows для профессионалов" (Рус., 2970 Kb)

Класс CDA

Этот класс (Class Dynamic Array) позволяет создавать массивы любых типов данных с динамическим выделением памяти. Он очень прост и обладает минимальной функциональностью, которой, однако, хватает для выполнения определенных задач. Память выделяется по мере надобности, освобождается же вся сразу.

template <class TYPE>
class CDA{
    public:
        // Зарезервировать регион для dwSize элементов массива
        BOOL Alloc( DWORD dwSize );

        // Возврат физической памяти региона
        void Decommit(){ VirtualFree( m_pArray, 0, MEM_DECOMMIT ); }   

        // Освобождение памяти региона
        void Release(){  VirtualFree( m_pArray, 0, MEM_RELEASE  ); }

        // Перегрузка оператора "[]" для доступа к элементам массива
        TYPE &operator[]( DWORD dwIndex );

    private:
        TYPE  *m_pArray;        // Указатель на начало массива
        DWORD  m_dwArraySize;   // Количество элементов в массиве
};

Резервирование региона:

template <class TYPE>
BOOL CDA<TYPE>::Alloc( DWORD dwSize )
{
    m_dwArraySize = dwSize;

    m_pArray = (TYPE*) VirtualAlloc( NULL, sizeof( TYPE ) * m_dwArraySize, 
                                     MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE );

    return ( m_pArray != NULL ) ? TRUE : FALSE;
}

Выделение физической памяти для элемента и возврат его адреса:

template <class TYPE>
TYPE &CDA<TYPE>::operator[]( DWORD dwIndex )
{
    // Если индекс выходит за пределы массива - устанавливаем его на последний элемент
    if( dwIndex > ( m_dwArraySize - 1 ) ) dwIndex = m_dwArraySize - 1;

    // Блок SEH
    __try{
         // Пытаемся произвести чтение
         TYPE t;
         CopyMemory( &t, &m_pArray[dwIndex], sizeof( TYPE ) );
        }
    __except( ( GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ) ?
                EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH ){
         // Произошло нарушение доступа - выделяем память
         VirtualAlloc( &m_pArray[dwIndex], sizeof( TYPE ), MEM_COMMIT, PAGE_READWRITE );
        }

    // Возвращаем адрес элемента
    return m_pArray[dwIndex];
}

Использование

CDA <DWORD> dwARRAY;

dwARRAY.Alloc( 1000000 );

dwARRAY[1]      = 1;
dwARRAY[10000]  = 10000;
dwARRAY[100000] = 100000;

dwARRAY.Release();

© 2003—2017 Игорь Разин