Программирование на языке MFC

Мой второй блог в серии программирования

Метод SetSize


Другими словами, при создании объекта у него нет данных, ас­социированных с ним, потому что указатель на ассоциированные с объектом данные m_pData равен NULL (о том, что представляет собой это поле, расскажу чуть позднее). Естественно, что в таком случае и размер данных (m_nSize), и размер приращения (mjiGrowBy) равны нулю. Назначение поля mjiMaxSize пока оста­ется не совсем понятным, но, надеюсь, его назначение скоро про­яснится. Кроме того, если размер массива можно изменять, то, зна­чит, мы имеем дело с так называемыми динамическими масси­вами! Причем, динамическими их можно назвать не в том смыс­ле, что память для них выделяется во время работы программы, а в том смысле, что размерность массивов может изменяться!

Исходя из этого, нам нужно узнать, каким образом происходит установка размера массива, а также как осуществляется увеличе­ние размера памяти, выделенного для массива.

Для изменения размера памяти, выделенного массиву, исполь­зуется метод SetSize():

void СОЬАггау::SetSize(int nNewSize, int nGrowBy) {

ASSERT_VALID(this); ASSERT(nNewSize >= 0);

if (nGrowBy != -JJ

m_nGrowBy = nGrowBy; // set new size

if (nNewSize == 0) {

// shrink to nothing delete[] (BYTE*)m_pData; m_pData = NULL; m_nSize = m_nMaxSize = 0;

}

else if (m_pData == NULL) {

// create one with exact size #ifdef SIZE_T_MAX

ASSERT(nNewSize <= SIZE_T_MAX/sizeof(CObject*) ) ;

// no overflow

#endif

m_pData = (CObject**) new BYTE[nNewSize *

sizebf(CObject*)];

memset(m_pData, 0, nNewSize * sizeof(CObject*));

// zero fill

m_nSize = m_nMaxSize = nNewSize;

}

else if (nNewSize <= m_nMaxSize) {

// it fits

if (nNewSize > m_nSize) {

// initialize the new elements memset(&m_pData[m_nSize], 0,

(nNewSize-m_nSize) * sizeof(CObject*));

}

m_nSize = nNewSize;

}

else {

// otherwise, grow array int nGrowBy = m_nGrowBy; if (nGrowBy == 0) {

// heuristically determine growth when nGrowBy == 0 // (this avoids heap fragmentation in many situations) nGrowBy = min(1024, max(4, m_nSize / 8));

}

int nNewMax;

if (nNewSize < m_nMaxSize + nGrowBy)

nNewMax = m_nMaxSize + nGrowBy; // granularity else

nNewMax = nNewSize; // no slush

ASSERT(nNewMax >= m_nMaxSize); // no wrap around #ifdef SIZE_T_MAX

ASSERT(nNewMax <= SIZE_T_MAX/sizeof(CObject*));

// no overflow

#endif

CObject** pNewData = (CObject**) new BYTE[nNewMax *

sizeof(CObject*)];

// copy new data from old

memcpy(pNewData, m_pData, m_nSize * sizeof(CObject*));

// construct remaining elements ASSERT(nNewSize > m_nSize);

memset(SpNewData[m_nSize], 0,

(nNewSize-m_nSize) * sizeof(CObject*));

// get rid of old stuff (note: no destructors called) delete[] (BYTE*)m_pData; m_pData = pNewData; m_nSize = nNewSize; m_nMaxSize = nNewMax;

}

}

Похожие статьи: