problem in multiplying arrays

Hi, this is my code.It's simple : there are 2 2D arrays and the multiplied to C.

#include<stdio.h>
#include<sys/shm.h>
#include<sys/stat.h>
#include<stdlib.h>

main()
{
        int *A;      //A[2][3]
        int *B;      //B[3][4]
        int *C;      //C[2][4]
        int i,j,x,k,d;
        int id;
        id = shmget(IPC_PRIVATE,4096, IPC_CREAT|0666);
        A = (int *)shmat(id,NULL, 0);
        x=1;

        for(i=0;i<2;i++)
        {
                for(j=0;j<3;j++)
                {
                        A[j*3+i]=x;
                        x++;
                }
        }

        B = (int *)shmat(id,NULL, 0);
        x=12;
        for(i=0;i<3;i++)
        {
                for(j=0;j<4;j++)
                {
                        B[j*4+i]=x;
                        x--;
                }
        }


        printf("A:\n");
        for(i=0;i<2;i++)
        {
                for(j=0;j<3;j++)
                {
                        printf("%d\t",A[j*3+i]);
                }
                printf("\n");
        }

        printf("B:\n");
        for(i=0;i<3;i++)
        {
                for(j=0;j<4;j++)
                {
                        printf("%d\t",B[j*4+i]);
                }
                printf("\n");
        }

        //Multiply to C[2][4], k common A,B
        C = (int *)shmat(id,NULL, 0);
        for(i=0;i<2;i++)
        {
                for(j=0;j<4;j++)
                {
                        for(k=0;k<3;k++)
                        {
                                d=d+A[k*3+i]*B[j*4+k];
                        }
                        C[j*4+i]=d;
                        d=0;
                }
        }

        printf("C:\n");
        for(i=0;i<2;i++)
        {
                for(j=0;j<4;j++)
                {
                        printf("%d\t",C[j*4+i]);
                }
                printf("\n");
        }
        shmdt(A);
        shmdt(B);
        shmdt(C);
        shmctl(id,IPC_RMID,NULL);
}

A should be:
1 2 3
4 5 6
and B:
12 11 10 9
8 7 6 5
4 3 2 1
but what i take is that:

A:
12	2	3	
8	11	6	
B:
12	11	10	9	
8	7	6	5	
4	3	2	1	
C:
172	1915	1738	1561	
16720	32032223	29070862	26109501	

C is also wrong...
Any ideas??

Indenting your program so I can read it.

#include<stdio.h>
#include<sys/shm.h>
#include<sys/stat.h>
#include<stdlib.h>

main()
{
        int *A;      //A[2][3]
        int *B;      //B[3][4]
        int *C;      //C[2][4]
        int i,j,x,k,d;
        int id;
        id = shmget(IPC_PRIVATE,4096, IPC_CREAT|0666);
        A = (int *)shmat(id,NULL, 0);
        x=1;

        for(i=0;i<2;i++)
        {
                for(j=0;j<3;j++)
                {
                        A[j*3+i]=x;
                        x++;
                }
        }

        B = (int *)shmat(id,NULL, 0);
        x=12;
        for(i=0;i<3;i++)
        {
                for(j=0;j<4;j++)
                {
                        B[j*4+i]=x;
                        x--;
                }
        }


        printf("A:\n");
        for(i=0;i<2;i++)
        {
                for(j=0;j<3;j++)
                {
                        printf("%d\t",A[j*3+i]);
                }
                printf("\n");
        }

        printf("B:\n");
        for(i=0;i<3;i++)
        {
                for(j=0;j<4;j++)
                {
                        printf("%d\t",B[j*4+i]);
                }
                printf("\n");
        }

        //Multiply to C[2][4], k common A,B
        C = (int *)shmat(id,NULL, 0);
        for(i=0;i<2;i++)
        {
                for(j=0;j<4;j++)
                {
                        for(k=0;k<3;k++)
                        {
                                d=d+A[k*3+i]*B[j*4+k];
                        }
                        C[j*4+i]=d;
                        d=0;
                }
        }

        printf("C:\n");
        for(i=0;i<2;i++)
        {
                for(j=0;j<4;j++)
                {
                        printf("%d\t",C[j*4+i]);
                }
                printf("\n");
        }
        shmdt(A);
        shmdt(B);
        shmdt(C);
        shmctl(id,IPC_RMID,NULL);
}

---------- Post updated at 01:42 PM ---------- Previous update was at 01:38 PM ----------

        A[0]=0xdeadbeef;
        printf("%x %x %x\n", A[0], B[0], C[0]);
deadbeef deadbeef deadbeef

A, B, and C are all pointers to the same memory. You're getting the exact same segment ID three times in a row, which gives you the exact same segment three times in a row.

Since you're getting 4096 bytes of memory anyway, plenty of room for all those small arrays in one call, why not just do this:

A=(int *)shmat(id,NULL, 0);
B=(A + (3*4));
C=(B + (3*4));

Then you get correct results for A and B, but not C. I'm not quite sure what you're doing with C.

Sorry about the lining...i fix it.

Your code is helpful. Now i get the right A and B arrays !
But I get for C that :

C:
40	34	28	53	
112	97	82	726	

but it should be:

C:
40	34	28	22	
112	97	82	67

Maybe a wrong at the multiply??
I thaught that this:

for(i=0;i<2;i++)
        {
                for(j=0;j<4;j++)
                {
                        for(k=0;k<3;k++)
                        {
                                d=d+A[k*3+i]*B[j*4+k];
                        }
                        C[j*4+i]=d;
                        d=0;
                }
        }

is the correct multiply code for 2 multidimensional 2Ds arrays.
k=3 is the A columns = B rows.
Is there any other way ??

Been a while since I did matrix multiplication, going through the math.

Of course...
i based here http://en.wikipedia.org/wiki/Matrix_multiplication for the multiplication
and here http://sourcecookbook.com/en/recipes/67/how-to-use-multidimensional-arrays-in-shared-memory-with-ipc for the arrays

You have problems initializing and printing your A array, multiplying by j instead of i so you try to assign 3 rows of 2 instead of 2 rows of 3... Fixing that makes A print rotated 90 degrees to B... Working on it...

---------- Post updated at 02:51 PM ---------- Previous update was at 02:46 PM ----------

You've got your rows and columns mixed up in general I think. A[(row*3) + column] not vice versa.

---------- Post updated at 03:06 PM ---------- Previous update was at 02:51 PM ----------

I found myself making the same mistake as you over and over. When that keeps happening that's a good sign it's time to let the computer start remembering some things instead of the programmer:

#define OFFSET(COLUMNS, ROW, COL)       ((ROW*COLUMNS)+COL)

...

       A = (int *)shmat(id,NULL, 0);
       B = A + OFFSET(3, 2, 0);
       C = B + OFFSET(3, 4, 0);

...

        x=1;
        for(i=0; i<2; i++)
        for(j=0; j<3; j++)
                A[OFFSET(3, i, j)]=x++;


...

        for(i=0; i<2; i++)
        for(j=0; j<4; j++)
        {
                int d=0, k;
                for(k=0; k<3; k++)
                        d += A[OFFSET(3,i,k)] * B[OFFSET(4,k,j)];

                C[OFFSET(4, j, i)]=d;
        }


...
#define OFFSET(COLUMNS, ROW, COL)       ((ROW*COLUMNS)+COL)

#include<stdio.h>
#include<sys/shm.h>
#include<sys/stat.h>
#include<stdlib.h>
main()
{
  int *A,*B,*C;
  int i,j,x,d,k;
  int id;
  id = shmget(IPC_PRIVATE,4096, IPC_CREAT|0666);
  A = (int *)shmat(id,NULL, 0);
  B = A + OFFSET(3, 2, 0);
  C = B + OFFSET(3, 4, 0);

  x=1;
  for(i=0; i<2; i++)
  {
    for(j=0; j<3; j++)
    {
      A[OFFSET(3, i, j)]=x++;
    }
  }
		
  x=12;
  for(i=0; i<3; i++)
  {
    for(j=0; j<4; j++)
    {
      B[OFFSET(4, i, j)]=x--;
    }
  }

   for(i=0; i<2; i++)
   {
     for(j=0; j<4; j++)
     {
                int d=0, k;
                for(k=0; k<3; k++)
                d += A[OFFSET(3,i,k)] * B[OFFSET(4,k,j)];
                C[OFFSET(4, j, i)]=d;
     }
   }
        
   printf("C:\n");
   for(i=0;i<2;i++)
   {
     for(j=0;j<4;j++)
     {
       printf("%d\t",C[j*4+i]);       
     }
     printf("\n");
   }
}

Yes! That do the job !
If you have the time can you explain me a little these lines:

B = A + OFFSET(3, 2, 0);
C = B + OFFSET(3, 4, 0)

and what does the OFFSET do ?
Also why its wrong with the 3 shmat() functions? In another program i made where A and B were read by a .txt file the arrays are correct.
I am at beginner level and i am trying a project... Of course this is not all of it. I just split it to pieces so i can do it easier.

It's the same as B = A + (3*2). Just reusing my code.

shmat() always gives you the same memory for the same ID -- that's what lets you share it between processes, you get the same memory.

// process 1

int *mem=shmat(...);

mem[0]=0xdeadbeef;

// process 2

int *mem=shmat(...);
printf("%d\n", mem[0]); // should print deadbeef if process 2 runs after 1

Modify it in one process and it gets modified in the other.

The idea's the same here, except you were using the same segment in the same process three times. It's not like malloc(), where you get new memory each time. Modify A and you modify B and C.

If you want three different segments, you need 3 different IDs. Or you can just use different memory in the same segment, like I did.

 A[0]=0xdeadbeef;
        printf("%x %x %x\n", A[0], B[0], C[0]);

To avoid that, I use different areas of the same segment for different matrices. It's sort of like this:

int bigarray[]={1, 2, 3, 4, 5, 6, // 6 elements
        12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, // 12 elements
        0, 0, 0, 0, 0, 0, 0, 0 // 8 elements
        };

int *A=bigarray; // Starts at element 0
int *B=A+(2*3); // Starts at element 6
int *C=B+(3*4); // Starts at element 18

I couldn't tell you what your other program was doing. I can't see your computer from here.

I understand.

But can't i just use the easy way with arrays, like that:

...
int A[2][3];
A=(int *)shmat(id,NULL,0);
...

I googled before i start the project and i found that arrays can be saved only with this way in shared memory.
If i could save them in the easy way that would be very helpful for my project.

Well, it depends... Are these arrays going to change in size, at all, ever? Or are they going to be a fixed size, forever?

If they're going to be the same size forever, you can do this:

struct shared {
        int A[2][3];
        int B[4][3];
        int C[4][2];
};

struct shared *s=(struct shared *)shmat(id,NULL, 0);

x=1;
for(i=0; i<2; i++)
for(j=0; j<3; j++)
        s->A[j]=x++;

x=12;
for(i=0; i<4; i++)
for(j=0; j<3; j++)
        s->B[j]=x--;

---------- Post updated at 04:27 PM ---------- Previous update was at 04:17 PM ----------

In fact you can put any kind of data structure you want in shared memory, as long as it doesn't contain pointers.

They are going to be in fixed sized during the program...
In fact i read their size from the .txt and also their contents from i, so they are going to be like that:

struct shared {
        int A[l][m];
        int B[m][n];
        int C[l][n];
};

So maybe with the struct i'll do the job.
I'll try it thanks!

That's mutually exclusive.

If they're fixed in size, they don't change and therefore can't be set at runtime.

That won't work. l, m, n have to be constant numbers. That's why I asked whether they ever change.

---------- Post updated at 05:00 PM ---------- Previous update was at 04:51 PM ----------

You can do something like this:

#define A(R,C)        a[(a_columns*R)+C]
#define B(R,C)        b[(b_columns*R)+C]
#define C(R,C)        c[(c_columns*R)+C]

int main(void)
{
        int a_columns=3, a_rows=2;
        int b_columns=4, b_rows=3;
        int c_columns=4, c_rows=2;

        int *a=shmat(...);
        int *b=a + (a_rows * a_columns);
        int *c=b + (b_rows * b_columns);

        for(i=0; i<2; i++)
        for(j=0; j<3; j++)
                A(i, j)=x++;
}

Or this:

// Cheap substitution trick.
// ARR(zzz, R, C) becomes zzz[(zzz_columns * R) + C]
// So this won't work unless a zzz_columns variable actually exists.
#define ARR(NAME,R,C)        NAME[(NAME ## _columns*R)+C]

// ARR_SIZE(yyy) becomes (yyy_columms * yyy_rows)
// so yyy_columns and yyy_rows need to exist somewhere if you do that!
#define ARR_SIZE(NAME)  (NAME ## _columns * NAME ## _rows)

int main(void)
{
        int A_columns=3, A_rows=2;
        int B_columns=4, B_rows=3;
        int C_columns=4, C_rows=2;
        
        int *A=shmat(...);
        int *B=A+ARR_SIZE(A);
        int *C=B+ARR_SIZE(B);

        for(i=0; i<A_rows; i++)
        for(j=0; j<A_columns; j++)
                ARR(A, i, j)=x++;
}

Trying it ....

these are my programs but i get this error at both:

main.c: In function �main':
main.c:33:22: error: called object �a' is not a function
main.c:43:22: error: called object �b' is not a function
main.c:115:34: error: called object �c' is not a function

You use a(i,j) in many places you should be using A(i,j).

pff
problems appear again..
the error is gone,also a and b arrays are right but i c give me 0 in every i,j .
i think i call the arrays wrong at compute.c:

int *a,*b,*c;
a=(int *)shmat(id,NULL,0);

b=(int *)shmat(id,NULL,0);

c=(int *)shmat(id,NULL,0);

is this the right way or i have to call the arrays like in the main ??

As explained many times in the last 2 pages, that sets all three arrays to the SAME MEMORY. It doesn't matter where you put that wrong code, it doesn't make it right code.

int *A=shmat(...);
int *B=A+(2*3);
int *C=B+(3*4);

ooo
sorry!

i try it this way too but i forgot a line with shmat and it gave me only zeros.
Thanks for everything, now i have to work for the other...
Thanks for your time!:b: