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 *vxin the prototype tofloat *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().