全國最多中醫師線上諮詢網站-台灣中醫網
發文 回覆 瀏覽次數:6821
推到 Plurk!
推到 Facebook!

memcpy 如何 copy 動態 2維陣列

 
MyBCB
一般會員


發表:4
回覆:7
積分:2
註冊:2006-07-16

發送簡訊給我
#1 引用回覆 回覆 發表時間:2006-07-16 23:16:29 IP:211.74.xxx.xxx 訂閱

我有一個很大的2維陣列,如下程式

想要用 memcpy 把這個2維陣列 copy到另外一個由matlab宣告的2維陣列,

但是這樣使用都一直有問題?

若2維陣列改用下方式,就可以使用,但問題是不能宣告double dbl2[4096][4096]或更大的;

會出現stack overflow!

double dbl2[3][3]={{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};

我有注意到這兩種2維陣的實際的型態是有差異,只是都可以用 dbl2[ ][ ] 的方式得到每一個元素值!

但是沒有idea做快速動態 2維陣列的copy ~~

請問各位先進,有沒有辦法解決呢?

PS. mxGetPr 函式將回傳一個 double * 指向資料的開頭

int i,j,z;
double **dbl2=new double*[4096];
for(i=0;i<4096;i )
dbl2[i]=new double[4096];

z=1;
for (i=0;i<4096;i )
for (j=0;j<4096;j )
{
dbl2[i][j]=z;
z ;
}

mxArray *A;
//建立一4096*4096的矩陣
A=mxCreateDoubleMatrix(4096, 4096, mxREAL);
//建立A矩陣於記憶體空間中
memcpy(mxGetPr(A), dbl2, 4096*4096 * sizeof(double));

MyBCB
一般會員


發表:4
回覆:7
積分:2
註冊:2006-07-16

發送簡訊給我
#2 引用回覆 回覆 發表時間:2006-07-17 01:21:28 IP:211.74.xxx.xxx 訂閱

我曾在別的論壇看到相似的討論,試了dynamic_2d_array,還是不行

現在只能土法煉鋼,一個一個塞~

Comment from eddisonan
Date: 06/01/2005 12:22PM PDT
Author Comment

i need to copy my c array to matlab using
memcpy((char *)mxGetPr(data), (char *)&b, (s*s*sizeof(double))

where
(char *)mxGetPr(data) is the destination
(char *)&b is the source

when i define a static array, let's say b[10][10], it works out fine

but i am using the dynamic array, it seems having problems of copying the b to data.

have u got any idea?

Accepted Answer from Axter
Date: 06/01/2005 12:29PM PDT
Grade: A
Accepted Answer

For C compatibility, you need to either use a 2D array build using code logic like that in the Allocate2DArray function I posted, or you need to use a wrapper like the one in the following link:
http://code.axter.com/dynamic_2d_array.h

Both these methods creates a single block array for the 2D array structure, which is compatible to a C static 2D array.

A vector-vector method is not garanteed to build a single block of memory for the 2D array.
Nor is any method that calls new over and over again.

You could try to consolidate the logic in the above link with that in the previous dynamic_2d_array class that I posted which has the boundry check.
MyBCB
一般會員


發表:4
回覆:7
積分:2
註冊:2006-07-16

發送簡訊給我
#3 引用回覆 回覆 發表時間:2006-07-17 01:43:23 IP:211.74.xxx.xxx 訂閱

試了Allocate2DArray,但是copy的內容不對!

template < typename T >
T **Allocate2DArray( int nRows, int nCols)
{
T **ppi;
T *pool;
T *curPtr;
//(step 1) allocate memory for array of elements of column

ppi = new T*[nRows];

//(step 2) allocate memory for array of elements of each row
pool = new T [nRows * nCols];

// Now point the pointers in the right place
curPtr = pool;
for( int i = 0; i < nRows; i )
{
*(ppi i) = curPtr;
curPtr = nCols;
}
return ppi;
}

template < typename T >
void Free2DArray(T** Array)
{
delete [] *Array;
delete [] Array;
}

MyBCB
一般會員


發表:4
回覆:7
積分:2
註冊:2006-07-16

發送簡訊給我
#4 引用回覆 回覆 發表時間:2006-07-17 01:46:42 IP:211.74.xxx.xxx 訂閱

自問自答~~

Allocate2DArray 就可以了,試出來囉!!!

CoffeeX
中階會員


發表:18
回覆:121
積分:72
註冊:2005-02-18

發送簡訊給我
#5 引用回覆 回覆 發表時間:2006-08-16 22:58:50 IP:140.125.xxx.xxx 未訂閱

感謝你的熱心,

讓我增長了些見識,

想結合matlab與bcb的人應該會很需要
===================引 用 文 章===================

自問自答~~

Allocate2DArray 就可以了,試出來囉!!!

------
=.=???
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#6 引用回覆 回覆 發表時間:2006-08-17 12:18:23 IP:61.229.xxx.xxx 未訂閱

這個題目很經典,忍不住要出來讚賞一下!

看了之前用class template透過vector來實作的部份,覺得真的有些繁鎖! 而上面使用的是function template,極少看到有人實作,但很經典! 它修改了c 無法使用(其實也不是無法是要經過複雜的macro)的prameterized type,省去寫
float **Allocate2DArray_OfFloat
double **Allocate2DArray_OfDouble
.........
.........

使用gereric 演算法就搞定!

此演算法是先配一個pointer block,然後再配置整個陣列的data block。再來把配好的整個陣列分段(分欄),並把每欄的開始的位址一一設配好的pointer block,這樣就形成了傳統c 語法的 pointer-pointer的型式,進而可用一般的陣列[ ]符號操作!

真是太經典的可學習範本: 可以了解二維陣列的初始,也了解指標的指標,也了解 c 裡的tmplate功能,對剛學 c 的人是個好題目!

------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
aftcast
站務副站長


發表:81
回覆:1485
積分:1763
註冊:2002-11-21

發送簡訊給我
#7 引用回覆 回覆 發表時間:2006-08-17 13:07:19 IP:61.229.xxx.xxx 未訂閱

補充一下,把 純 C 版的也放上來給大家參考

#include /*for printf ...*/
#include /* for C version malloc*/


/* -----------------------pure C version---------------*/
void **Allocate2DArray(int TypeSize, int x, int y)
{
void **ppi = (void **) malloc(x*sizeof(void*));
void *pool = (void *) malloc(x*y*TypeSize);
unsigned char *curPtr = (unsigned char *) pool;
int i;
if (!ppi || !pool)
{ /* Quit if either allocation failed */
if (ppi) free(ppi);
if (pool) free(pool);
return NULL;
}

for(i = 0; i < x; i )
{
*(ppi i) = curPtr;
curPtr = y*TypeSize;
}
return ppi;
}

void Free2DArray(void ** Array)
{
free(*Array);
free(Array);
}


template < typename T >
T **Allocate2DArray( int nRows, int nCols)
{
T **ppi;
T *pool;
T *curPtr;
//(step 1) allocate memory for array of elements of column

ppi = new T*[nRows];

//(step 2) allocate memory for array of elements of each row
pool = new T [nRows * nCols];

// Now point the pointers in the right place
curPtr = pool;
for( int i = 0; i < nRows; i )
{
*(ppi i) = curPtr;
curPtr = nCols;
}
return ppi;
}

template < typename T >
void Free2DArray(T** Array)
{
delete [] *Array;
delete [] Array;
}

int main(void)
{
double **d = Allocate2DArray(10000, 10000);
d[0][0] = 10.0;
d[1][1] = 30.0;
d[9999][9999] = 1234.56;
puts("C template version");
printf("d[0][0]=%7.2f,d[1][1]=%7.2f,d[999][9999]=%7.2f"
,d[0][0],d[1][1],d[9999][9999]);
Free2DArray(d);

/* C void** version --------------------------------*/
double **f = (double**) Allocate2DArray(8, 10000, 10000);
f[0][0] = 10.0;
f[1][1] = 30.0;
f[9999][9999] = 1234.56;
puts("\nC void** version");
printf("f[0][0]=%7.2f,f[1][1]=%7.2f,f[999][9999]=%7.2f"
,f[0][0],f[1][1],f[9999][9999]);
Free2DArray((void**)f);
}

------


蕭沖
--All ideas are worthless unless implemented--

C++ Builder Delphi Taiwan G+ 社群
http://bit.ly/cbtaiwan
系統時間:2024-11-23 13:07:57
聯絡我們 | Delphi K.Top討論版
本站聲明
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。
2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。
3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇!