put an 2D array in shared memory

Hi,
I want to make 2 simple programs communicate each other with shared memory.
The programs will share an 2D array. In the first program (intarr.c) i create an x[3][4] array which is:
1 2 3 4
5 6 7 8
9 10 11 12
and i call the second program (intarr2.c) with execvp(); giving it the segment id as an argument. The intarr2.c just print the array to the terminal.

/*intarr.c*/
#include<stdio.h>
#include<sys/shm.h>
#include<sys/stat.h>
main()
{
  int segid,i,j,y;
  int *x[3][4];
  segid=shmget(IPC_PRIVATE,512,S_IRUSR|S_IWUSR);
  x[3][4]=(int *)shmat(segid,NULL,0);
  y=1;
  for(i=0;i<3;i++)
  {
    for(j=0;j<4;j++)
    {
      *x[j]=y;
      y++;
    }
  }
  char str[100+1] = {'\0'};
  sprintf( str, "%d", segid );
  const char *argv[]={"./intarr2.out",str,(char *)NULL};
  execvp("./intarr2.out",argv);
  shmdt(x);
  shmctl(segid,IPC_RMID,NULL);
  return 0;
}
/*intarr2.c*/
#include<stdio.h>
#include<sys/shm.h>
#include<sys/stat.h>

main(int argc,char *argv[])
{
  int *x[3][4];
  x[3][4]=(int *)shmat(atoi(argv[1]),NULL,0);
  int i,j;
  for(i=0;i<3;i++)
  {
    for(j=0;j<4;j++)
    {
      printf("%d\t",*x[j]);
    }
    printf("\n");
  }
}
/*Terminal*/
x@ubuntu:~/x$ gcc intarr2.c -o intarr2.out
x@ubuntu:~/x$ gcc intarr.c
x@ubuntu:~/x$ ./a.out
Segmentation fault

With this code i dont get any warning or error with gcc.
But the ./a.out gives me Segmentation fault.
Any ideas?:confused:

Probably operator precedence, among other problems.

  int *x[3][4];

If with that you're trying to define "x" as a pointer to a 3x4 array, I think offhand what you're actually getting is a 3x4 array of integer pointers. I'd guess that's probably not what you want.

And this:

  x[3][4]=(int *)shmat(atoi(argv[1]),NULL,0);

That assigns the address of the shared memory segment to the [3][4] element of your array. That's almost certainly NOT what you want to do.

This definition might work, but I'm not going to dig through all the C operator precedence rules to find out:

int *(x[3][4]);

You can always use typedef's to make it easier, because then you can build your complex declaration step-by-step:

typedef int intFourArray[4];
typedef intfourarray intThreeByFourArray[3];
typedef intThreeByFourArray *intThreeByFourArrayPtr;
1 Like

I google search it a little and i create this code which does the job :

/*intarr.c*/
#include<stdio.h>
#include<sys/shm.h>
#include<sys/stat.h>
main()
{
  int rows=3;
  int columns=4;
  int *matrix;
  int segid,y,i,j;
  segid=shmget(IPC_PRIVATE,sizeof(int)*rows*columns,S_IRUSR|S_IWUSR);
  matrix = (int *)shmat(segid,NULL,0);
  y=1;
  for (i = 0; i < rows; i++)
  {
    for (j = 0; j < columns; j++)
    {
        matrix[i*columns + j] = y;
        y++;
    }
  }
  char strid[100+1] = {'\0'};
  sprintf( strid, "%d", segid );
  char strrow[100+1] = {'\0'};
  sprintf( strrow, "%d", rows );
  char strcolumn[100+1] = {'\0'};
  sprintf( strcolumn, "%d", columns );
  const char *argv[]={"./intarr2.out",strid,strrow,strcolumn,(char *)NULL};
  execvp("./intarr2.out",argv);
  shmdt(matrix);
  shmctl(segid,IPC_RMID,NULL);
  return 0;
}
/*intarr2.c*/
#include<stdio.h>
#include<sys/shm.h>
#include<sys/stat.h>

main(int argc,char *argv[])
{
  int row;
  int column;
  row=atoi(argv[2]);
  column=atoi(argv[3]);
  int *matrix;
  matrix=(int *)shmat(atoi(argv[1]),NULL,0);
  int i,j;
  for(i=0;i<3;i++)
  {
    for(j=0;j<4;j++)
    {
      printf("%d\t",matrix[i*column+j]);
    }
    printf("\n");
  }
}

If there is a more correct way i'm willing to know ...
Thanks :b: