• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1246
  • Last Modified:

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.
0
trubiat
Asked:
trubiat
  • 5
  • 4
1 Solution
 
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
 
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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
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

Featured Post

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

  • 5
  • 4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now