2012-11-27 175 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()结果的内存布局假设的不准确性。 –