

Программирование на языке 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;
}
}
Похожие статьи: Метод SetSize
