kitty
kitty

Reputation: 717

Replacing for loop with memcpy in C won't work

I should try to make a simple 2-D heat calculation using Jacobi more efficient in C. After calculating the new array I have to copy the new values into the old array.

At the moment a for loop is used:

    for (j = 1; j < sizex - 1; j++) {
                    for (i = 1; i < sizey - 1; i++) {
                            u[j * sizex + i] = utmp[j * sizex + i];
                    }
            }

My thought was to use memcpy instead, but I think I am doing something wrong:

    memcpy(u, utmp,sizex*sizey*sizeof(unsigned));

My results are completely wrong after using memcpy instead of the for loop.

The whole function:

void relax_jacobi(double *u, double *utmp, unsigned sizex, unsigned sizey) {
        int i, j;
        double unew, diff, sum = 0.0;
        for (j = 1; j < sizex - 1; j++) {
                for (i = 1; i < sizey - 1; i++) {
                        utmp[j * sizex + i] = 0.25 * (u[j * sizex + (i - 1)] +
                                                u[j * sizex + (i + 1)] +
                                                u[(j - 1) * sizex + i] +
                                                u[(j + 1) * sizex + i]);
                }
        }

        /*for (j = 1; j < sizex - 1; j++) {
                for (i = 1; i < sizey - 1; i++) {
                        u[j * sizex + i] = utmp[j * sizex + i];
                }
        }*/
        memcpy(u,utmp,sizex*sizex*sizeof(double));
}

What am I doing wrong? I never really worked with C before. Is it even the right approach?

The for loop starts at 1, as the 2x2 Grid won't change at the edges.

Upvotes: 0

Views: 73

Answers (1)

chux
chux

Reputation: 153303

OP's memcpy(u, utmp,sizex*sizey*sizeof(double)); (which copies all the matrix) is not the same code as below code is copying all but the outer 4 edges of the 2D matrix.

for (j = 1; j < sizex - 1; j++) {
  for (i = 1; i < sizey - 1; i++) {
    u[j * sizex + i] = utmp[j * sizex + i];
  }
}

is like

for (j = 1; j < sizex - 1; j++) {
  // Copy 1 inner sub-row at a time.
  memcpy(&u[j * sizex + 1], &temp[j * sizex + 1], sizeof *u * (sizey-2));
}

Use sizeof *u instead of sizeof (double) to avoid coding errors (as OP originally posted).

Upvotes: 2

Related Questions