2012-11-27 322 views
0

我有一個MPI程序,用於MPI C中的圖像處理(pgm文件),我使用如下的二維數組的動態分配。動態分配二維數組與C簡單的二維數組Mpi

float **masterbuf; 
masterbuf = arralloc(sizeof(float), 2, M, N); 

當我使用

float masterbuf[M][N]; 

,該方案使圖像看起來很好。

問題是,當我使用動態分配時,圖像的左側會丟失一些像素。所以這些缺失的像素會產生一條黑線。這就像圖像右移了2個像素。我不會對圖像執行任何其他操作,只需閱讀並再次打印即可。

,我用它來寫圖像的功能是:

void pgmwrite(char *filename, void *vx, int nx, int ny) 
{ 
    FILE *fp; 

    int i, j, k, grey; 

    float xmin, xmax, tmp, fval; 
    float thresh = 255.0; 

    float *x = (float *) vx; 

    if (NULL == (fp = fopen(filename,"w"))) 
    { 
    fprintf(stderr, "pgmwrite: cannot create <%s>\n", filename); 
    exit(-1); 
    } 

    printf("Writing %d x %d picture into file: %s\n", nx, ny, filename); 

    /* 
    * Find the max and min absolute values of the array 
    */ 

    xmin = fabs(x[0]); 
    xmax = fabs(x[0]); 

    for (i=0; i < nx*ny; i++) 
    { 
    if (fabs(x[i]) < xmin) xmin = fabs(x[i]); 
    if (fabs(x[i]) > xmax) xmax = fabs(x[i]); 
    } 

    if (xmin == xmax) xmin = xmax-1.0; 

    fprintf(fp, "P2\n"); 
    fprintf(fp, "# Written by pgmwrite\n"); 
    fprintf(fp, "%d %d\n", nx, ny); 
    fprintf(fp, "%d\n", (int) thresh); 

    k = 0; 

    for (j=ny-1; j >=0 ; j--) 
    { 
    for (i=0; i < nx; i++) 
    { 
     /* 
     * Access the value of x[i][j] 
     */ 

     tmp = x[j+ny*i]; 

     /* 
     * Scale the value appropriately so it lies between 0 and thresh 
     */ 

     fval = thresh*((fabs(tmp)-xmin)/(xmax-xmin))+0.5; 
     grey = (int) fval; 

     fprintf(fp, "%3d ", grey); 

     if (0 == (k+1)%16) fprintf(fp, "\n"); 

     k++; 
    } 
    } 

    if (0 != k%16) fprintf(fp, "\n"); 
    fclose(fp); 
} 

回答

2

您的兩個masterbuf的定義既可以創建二維數組,但他們不以同樣的方式這樣做。函數arralloc()爲數據和指針創建空間 - 不僅僅是簡單靜態數組定義的數據。這意味着在pgmwrite()中,儘管x [i] [j]將返回相同的結果,而不管使用何種方法,但由於指針參與,x [i]將意味着兩件不同的事情。

值得注意的是,如果您將原型中的void *vx更改爲float *vx,那麼編譯器會提供線索。既然你立即無條件地將這個void *賦值給float *,那麼無論如何這樣做會更好。

(2nd edit :)此外,如果感興趣,請查看這response。它顯示瞭如何在沒有arralloc()的情況下使用兩個維度將索引編入單個malloc'd塊。

+0

不能,[arralloc](https://code.google.com/p/messagepassing/source/browse/trunk/arralloc.c)使用dope-vectors的概念,即將索引向量轉換爲大型數據塊。似乎現在互聯網上的EPCC代碼無處不在:) –

+0

非常感謝您的鏈接和信息!雖然答案的要點依然如故,但我已經大幅削減了它,主要是爲了消除有關arralloc()結果的內存佈局假設的不準確性。 –