动态分配2d数组在C差异与一个简单的2d阵列Mpi [英] Dynamic Allocation 2d array in C difference with a simple 2d array Mpi

查看:198
本文介绍了动态分配2d数组在C差异与一个简单的2d阵列Mpi的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在MPI C中有一个用于图像处理(pgm文件)的MPI程序,我使用如下的2D数组的动态分配。

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

当我使用

 [code] float masterbuf [M] [N]; 

程序给出的图像看起来不错。



问题是当我使用动态分配时,图像左侧会丢失一些像素。所以这些丢失的像素会产生黑线。就像图像已经移动了2像素。我不会对图像进行任何其他操作,只需读取并再次打印。



我用于写入图像的功能是:

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

int i,j,k,gray;

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

float * x =(float *)vx;

if(NULL ==(fp = fopen(filename,w)))
{
fprintf(stderr,pgmwrite:无法创建<%s> \\ n,filename);
exit(-1);
}

printf(将%d x%d图片写入文件:%s\\\
,nx,ny,filename);

/ *
*查找数组的最大和最小绝对值
* /

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

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

fprintf(fp,P2\\\
);
fprintf(fp,#由pgmwrite\\\
编写);
fprintf(fp,%d%d\\\
,nx,ny);
fprintf(fp,%d\\\
,(int)thresh);

k = 0; (i = 0; i
(j = ny-1; j> = 0; j--)
{ $ b {
/ *
*访问x [i] [j]的值
* /

tmp = x [j + ny * i];

/ *
*适当地缩放值,它位于0和thresh之间
* /

fval = thresh *((fabs(tmp) -xmin)/(XMAX-XMIN))+ 0.5;
gray =(int)fval;

fprintf(fp,%3d,灰色);

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

k ++;
}
}

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


解决方案

你对masterbuf的两个定义可能都创建2D数组,但它们不会以相同的方式执行。功能 arralloc()为数据创建空间,指针 - 不仅仅是简单的静态数组定义的数据。这意味着在pgmwrite()中,而x [i] [j]将返回相同的结果,无论使用哪种方法,x [i]将意味着两个不同的东西,因为指针的参与。 >

值得注意的是,您将被编译器给出一个线索,如果您更改 void * vx 原型为 float * vx 。由于您立即无条件地将此void *转换为浮点数*,所以无论如何,执行此操作会更好。



(第二个)另外,如果有兴趣,请查看此回复。它显示了如何使用二维来索引到单个malloc'd块中,而不使用arralloc()。


I have a MPI program for image processing (pgm file) in MPI C and I use Dynamic allocation for a 2D Array as follows.

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

When I use

float masterbuf[M][N];

the image that the program gives looks fine.

The problem is that when I use dynamic allocation the image loses some pixels in its left side. So these missing pixels create a black line. It's like the image has been shifted 2 pixels right. I don't do any other operations to the image, just read it and print it again.

The function that I use to write the image is:

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);
}

解决方案

Your two definitions of masterbuf may both create 2D arrays, but they don't do so in the same way. The function arralloc() creates space for data and pointers--not just data as with the simple static array definition. What this works out to mean is that in pgmwrite(), while x[i][j] will return the same result regardless of the method used, x[i] will mean two different things because of the pointer involvement.

It's worth noting that you'll be given a clue by the compiler as to the problem should you change void *vx in the prototype to float *vx. Since you're immediately and unconditionally casting this void * to a float *, it'd be much better practice to do this anyhow.

(2nd edit:) Also, if interested, check out this response. It shows how to index using two dimensions into a single malloc'd block, without arralloc().

这篇关于动态分配2d数组在C差异与一个简单的2d阵列Mpi的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆