這是我的改寫,自己覺得很有道理拉 XD
NR_END我覺得是為了記憶體宣告時不access overrun存在的
怎麼看我都覺得malloc時轉(size_t)很多餘,這樣做對於現在compiler應該很多餘吧
有錯請指指正,謝謝!
float **constraint_matrix(long nrl, long nrh, long ncl, long nch)
/* allocate a float matrix with subscript range m[nrl..nrh][ncl..nch] */
{
//利用記憶體是否初始的方式來執行range m[nrl..nrh][ncl..nch]
//也就是說對於一個(nrh+1)*(nrh+1)的矩陣, 除了m[nrl..nrh][ncl..nch]部份,記憶
//體的存取為無效(access violation),實際應用上只能以 m[rI][cI], rI<nrl
//記憶體存取無效的方式來實作,至於cI部分卻只能自行判斷,
//且為了保證range m[nrl..nrh][ncl..nch]在宣告記憶體時有效,
//因此需要宣告m[nrl+nrh][ncl+nch]大小的連續記憶體空間,以避免 memory access
//overrun
const int rowStart = nrl;
const int colStart = ncl;
long nrow=nrh-nrl+1,ncol=nch-ncl+1;
float **m;
/* allocate pointers to rows */
m=(float **) malloc((size_t)((nrow+rowStart)*sizeof(float*)));
if (!m) new Exception("allocation failure 1 in matrix()");
/* allocate rows and set pointers to them */
m[nrl]=(float *) malloc((size_t)((nrow*ncol+colStart)*sizeof(float)));
if (!m[nrl]) new Exception("allocation failure 2 in matrix()");
//initial矩陣m中(row index>nrl)的記憶體起始位址
for(int rI=nrl+1;rI<=nrh;rI++)
{
m[rI]=m[rI-1]+ncol;
memset(m[rI],-1, colStart*sizeof(float));//驗證使用
//理論上會將m[rI][0..colStart-1]設為0,
//實際上是將m[rI][last..last-colStart] 設為0
}
//承上, 所以若要將m[nrl..nrh][ncl..nch]設為0,應執行
for(int i=nrl; i<=nrh; i++)
memset(m[i]+colStart, 0, ncol*sizeof(float));
/* return pointer to array of pointers to rows */
return m;
}
※ 引述《realmeat (真肉)》之銘言:
: ※ 引述《HeyScng ( )》之銘言:
: : 剛剛在書中的程式看到的,不過目前還看不懂他在寫什麼,
: : 大概跑了一下也是抓不到規律,有興趣的人可以看看! 謝謝!
: :
: 跑了一下才知道它要幹嘛
: 難怪會取到軌異的位置去
: 簡單的說就是
: 取個矩陣只有指定的範圍才有宣告實體位置
: 其他則都沒宣告實體位置
: 寫法相當差, 很多無意義的程式碼
: 個人習慣, 全面性改寫
: float **matrix(long row_low, long row_high, long col_low, long col_high)
: {
: long i;
: long row_sub = row_high-row_low+1;
: long col_sub = col_high-col_low+1;
: // 宣告放指標的空間
: float **m=(float **) malloc((size_t)((row_sub)*sizeof(float*)));
: if (!m){
: //error ("allocation failure 1 in matrix()");
: return NULL;
: }
: // 宣告放float的空間
: float* m2=(float *) malloc((size_t)((row_sub*col_sub)*sizeof(float)));
: if (!m2){
: //error ("allocation failure 2 in matrix()");
: return NULL;
: }
: m[0] = m2-col_low; // 做col 位移
: // 依序填入值
: for(i=1; i<row_sub; i++){
: m[i] = m[i-1]+col_sub;
: }
: return &m[-row_low]; //做row 位移
: }
: 簡單的說就是宣告2次陣列的簡單程式
: 然後把位址移動一下欺騙程式就好了
: 寫那麼複雜是怎樣?
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 118.169.42.127
※ 編輯: HeyScng 來自: 118.169.42.127 (11/05 21:13)