這個問題應(yīng)該是我以前在CSDN蹭分時回答次數(shù)比較多的一個問題了,我的回答一般是三種方法:(1)用vector的vector,(2)先分配一個指針 數(shù)組,然后讓里面每一個指針再指向一個數(shù)組,這個做法的好處是訪問數(shù)組元素時比較直觀,可以用a[x][y]這樣的寫法,缺點是它相當(dāng)于C#中的一個鋸齒 數(shù)組,內(nèi)存空間不連續(xù)。(3)直接分配一個x*y大小的一維數(shù)組,這樣保證空間是連續(xù)的,但訪問數(shù)組元素不直觀。對于我這個“經(jīng)典”回答,我那時還一直是 挺得意的,至少從蹭分的角度來看,這樣回答還是很有效的。
今天在ChinaUnix論壇閑逛時看到一個貼子,再次證明了我在C++方面才疏學(xué)淺。
#include
#include
#include
void **darray_new(int row, int col, int size)
{
void **arr;
arr = (void **) malloc(sizeof(void *) * row + size * row * col); if (arr != NULL)
{
void *head;
head = (void *) arr + sizeof(void *) * row; memset(arr, 0, sizeof(void *) * row + size * row * col); while (row--)
arr[row] = head + size * row * col;
}
return arr;
}
void darray_free(void **arr)
{
if (arr != NULL)
free(arr);
}
嗯,連續(xù)分配內(nèi)存,而且可以用a[x][y]的方式來訪問!可謂二維數(shù)組動態(tài)分配的絕妙方法!這段程序是C的,似乎要改成支持對象分配的C++版也不是什么難事(不過估計得用上placement new吧,嗯,需要再思考一下……)。
經(jīng)過試驗,C++版出爐了:)關(guān)鍵點還是在于placement new和顯示的析構(gòu)函數(shù)調(diào)用,用于保證對象可以正常的構(gòu)造和析構(gòu)。
這個實現(xiàn)也還是有不少缺點的,比如,數(shù)組的大小必須記住,才能保證析構(gòu)所有對象。不過這點可以通過改進分配方法算法,把數(shù)組大小也用一點空間保存起來。
另一個缺點是,從語法上看,很容易讓人誤把darray_new返回的指針以為是數(shù)據(jù)區(qū)的起始地址,從而可能導(dǎo)致一些邏輯錯誤。
#include
#include
#include
template
T **darray_new(int row, int col)
{
int size = sizeof(T);
void **arr = (void **) malloc(sizeof(void *) * row + size * row * col);
if (arr != NULL)
{
unsigned char * head;
head = (unsigned char *) arr + sizeof(void *) * row;
for (int i = 0; i < row; ++i)
{
arr[i] = head + size * i * col;
for (int j = 0; j < col; ++j)
new (head + size * (i * col + j)) T;
}
}
return (T**) arr;
}
template
void darray_free(T **arr, int row, int col)
{
for (int i = 0; i < row; ++i)
for (int j = 0; j < col; ++j)
arr[i][j].~T();
if (arr != NULL)
free((void **)arr);
}
今天在ChinaUnix論壇閑逛時看到一個貼子,再次證明了我在C++方面才疏學(xué)淺。
#include
#include
#include
void **darray_new(int row, int col, int size)
{
void **arr;
arr = (void **) malloc(sizeof(void *) * row + size * row * col); if (arr != NULL)
{
void *head;
head = (void *) arr + sizeof(void *) * row; memset(arr, 0, sizeof(void *) * row + size * row * col); while (row--)
arr[row] = head + size * row * col;
}
return arr;
}
void darray_free(void **arr)
{
if (arr != NULL)
free(arr);
}
嗯,連續(xù)分配內(nèi)存,而且可以用a[x][y]的方式來訪問!可謂二維數(shù)組動態(tài)分配的絕妙方法!這段程序是C的,似乎要改成支持對象分配的C++版也不是什么難事(不過估計得用上placement new吧,嗯,需要再思考一下……)。
經(jīng)過試驗,C++版出爐了:)關(guān)鍵點還是在于placement new和顯示的析構(gòu)函數(shù)調(diào)用,用于保證對象可以正常的構(gòu)造和析構(gòu)。
這個實現(xiàn)也還是有不少缺點的,比如,數(shù)組的大小必須記住,才能保證析構(gòu)所有對象。不過這點可以通過改進分配方法算法,把數(shù)組大小也用一點空間保存起來。
另一個缺點是,從語法上看,很容易讓人誤把darray_new返回的指針以為是數(shù)據(jù)區(qū)的起始地址,從而可能導(dǎo)致一些邏輯錯誤。
#include
#include
#include
template
T **darray_new(int row, int col)
{
int size = sizeof(T);
void **arr = (void **) malloc(sizeof(void *) * row + size * row * col);
if (arr != NULL)
{
unsigned char * head;
head = (unsigned char *) arr + sizeof(void *) * row;
for (int i = 0; i < row; ++i)
{
arr[i] = head + size * i * col;
for (int j = 0; j < col; ++j)
new (head + size * (i * col + j)) T;
}
}
return (T**) arr;
}
template
void darray_free(T **arr, int row, int col)
{
for (int i = 0; i < row; ++i)
for (int j = 0; j < col; ++j)
arr[i][j].~T();
if (arr != NULL)
free((void **)arr);
}