• C

How can I declare a 2D array in shared memory?

I want to know how can I declare a 2D integer array and then store it into shared memory and then how to pass it to child processes. I have done this for a regular integer but I do not know how to do it for a 2D array.

int *times_written;
char *shm_addr;

myshmid = shmget (IPC_PRIVATE, sizeof(int), IPC_CREAT | 0600);
if (myshmid == -1)
      f_error("shmget failed");
shm_addr = shmat(myshmid, 0, 0);
times_written = (int*) shm_addr;

for(i = 0; i < pno; i++)
{
      if ((PID = fork()) == 0)
      {
            printf("Creating producer %d\n", i + 1);
            producer(i + 1, times_written);
            break;
      }
}

The producer method is as follows:

void producer(int thread_num, int * times_written)
{
      printf("PRODUCER #%d\n", thread_num);
      *times_written = *times_written + 1;
      printf("times_written is: %d\n", *times_written);
}

The above works well for a signle integer.

High priority question. 500 points.
trubiatAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ikeworkCommented:
hi trubiat,


here is an example:

// x.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//

#include <stdio.h>
#include <malloc.h>

static const int X_DIM_WIDTH = 10;
static const int Y_DIM_WIDTH = 5;

#define ACCESS_ARRAY( array, x, y ) (*((array)+(x)*X_DIM_WIDTH+(y)))

void producer(int *array2D)
{
      printf( "element [3][2] is : %d\n", ACCESS_ARRAY( array2D, 3, 2 ) );
}

int main(int argc, char* argv[])
{
      int *p = (int*)malloc( sizeof( int ) * X_DIM_WIDTH * Y_DIM_WIDTH );

      ACCESS_ARRAY( p, 3, 2 ) = 42;
      
      producer( p );

      free( p );
      p = NULL;
      return 0;
}

hope it helps,
ike
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
trubiatAuthor Commented:
I know how to do it with malloc() but I have to use shmget. Any idea how to do this?
0
ikeworkCommented:
what about:

int *array2D;
char *shm_addr;

myshmid = shmget (IPC_PRIVATE, sizeof(int) * X_DIM_WIDTH * Y_DIM_WIDTH, IPC_CREAT | 0600);
if (myshmid == -1)
     f_error("shmget failed");
shm_addr = shmat(myshmid, 0, 0);
array2D = (int*) shm_addr;


ike
0
Ultimate Tool Kit for Technology Solution Provider

Broken down into practical pointers and step-by-step instructions, the IT Service Excellence Tool Kit delivers expert advice for technology solution providers. Get your free copy now.

trubiatAuthor Commented:
i tried that and it compiles....but how do I pass it from parent to children and how do I access it from children?

Any idea how to share semaphores with shared memory or malloc?
0
ikeworkCommented:
>>  I have done this for a regular integer but I do not know how to do it for a 2D array

the same way you did it for that integer ...

0
trubiatAuthor Commented:
your code still gives a pointer to an integer. but it allocates more memory. That's not a 2D array....
0
ikeworkCommented:
>> your code still gives a pointer to an integer. but it allocates more memory. That's not a 2D array....

yes and no ... it gives an integer-pointer, pointing to a memory block of integers with size of X_DIM * Y_DIM.
now look at the makro  ACCESS_ARRAY() . it calculates the **linear address** from x & y and accesses
that element, thats a 2d-array ... :-)

0
trubiatAuthor Commented:
i guess you are right since i don't know much about C.

therefore how do u access the 2D array from a child process?

I tried Buffer[0][1] but it doesn't work...
0
sunnycoderCommented:
What you have done so far for single integer is perfectly fine. What you need to realize is that shared memory region that you created did not have any type associated with it. It is entirely upto you to fill it with data of your desired type.

shm_addr = shmat(myshmid, 0, 0);
times_written = (int*) shm_addr; >>>> why just cast it to int * ... you can cast it to int ** or int (*)[] .. or almost anything else!!!
0
ikeworkCommented:
you can only use this notation, if you know the dimensions( or at least the inner dimension, the right one) at compile-time, if the size of the array dimensions are dynamic, you cant use it, because the compiler needs this to know it to calc the array-item's-address.

are the dimensions of your array static, or do they change?
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.