動態分配二維陣列

看到動態配置,可能會寫下以下這段程式:
int** m_matrix = new int* [matrix_size];
for (int i = 0; i < matrix_size; ++i)
{
  m_matrix[i] = new int[matrix_size];
}

看起來是很合理,但是這卻不是真正的二維陣列,陣列是用連續的空間配置而成,以上的程式只是用數組一維陣列組合而成類二維陣列,並沒有達成真正的二維陣列,所以以上的m_matrix如果要釋放的話,必定要:
for (int i = 0; i < matrix_size; ++i)
{
  delete [] m_matrix[i];
}
delete [] m_matrix;
而不是delete [] m_matrix;,代表因為空間未連續,所以要找到每個一維陣列的頭才能刪除。
要做到真正的二維陣列,可以使用下列的程式:
void* malloc2d( int w, int h, int size )
{
  int j;
  void **a = (void**) malloc( h*sizeof(void*) + w*h*size );
  for( j=0; j<h; j++ )
    a[j] = ((char *)(a+h)) + j*w*size;
  return a;
}
使用時:
int **m = (int**)malloc2d(w,h,sizeof(int));
釋放時:
free(m);

此配置的方式是先配置好二維陣列所需佔用的記憶空間,此空間分為指標區(h * sizeof(void*))以及資料儲存區(w * h * size),然後再把指標區分別指向資料區的頭,a[j]為指標陣列的結束,資料儲存區的開始, w * size為資料儲存區每一列的長度,由下表可清楚了解:

如此一來,一整個空間就都是連續了,所以要釋放時也就只要從頭開始就可以了。以下是改用C++的new:
void* new2d(int w, int h, int size)
{
  void **a = (void**)new char[h * sizeof(void*) + w * h * size];
  
  for(int i = 0; i < h; ++i)
    a[i] = ((char*)(a + h)) + i * w * size;
    
  return a;
}
使用時:
int **m = (int**)new2d(w, h, sizeof(int));
釋放時:
delete[] m;

0 意見:

張貼留言