2D array through shared memory

Hello guys!

Is there a way to allocate a 2D array through shared memory?
I usually set it up like this:

1
2
3
    struct foo{
        char mat[HEIGHT][WIDTH];
    };


Then allocate and attach the memory:

1
2
3
    sh_mem = shmget(IPC_PRIVATE, sizeof(struct foo), 0666);
    struct foo* p;
    p = shmat(sh_mem, NULL, 0);


So i can easily manage the pointer like: p -> mat[x][y]
My question is: Can i allocate and manage a shared memory without going through a struct?

Thanks a lot.
Last edited on
if you can't find a way, 2d arrays are a solid block of memory and can be collapsed to a 1-d pointer and back at will (not so with **). I would think you could share it, but I have not tried to do so.
> Can i allocate and manage a shared memory without going through a struct?

If it is an array of bytes (character types), we could do something like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>

constexpr std::size_t HEIGHT = 1000 ;
constexpr std::size_t WIDTH = 2000 ;
using matrix_t = char[HEIGHT][WIDTH] ; // type alias for 2d array

int main()
{
    const int shm_id = ::shmget( IPC_PRIVATE, sizeof(matrix_t), IPC_CREAT | 0666 ) ;
    if( shm_id != -1 )
    {
        void* pv = ::shmat( shm_id, nullptr, 0 ) ;

        if( pv != nullptr )
        {
            matrix_t* pmat = static_cast<matrix_t*>(pv) ; // cast to pointer to the 2d char array type
            matrix_t& matrix = *pmat ; // get a reference to (an alias for) the array

            // use the array
            matrix[0][0] = 'a' ;

            // release shared memory etc.
        }
        
      // ...
    }
}
> My question is: Can i allocate and manage a shared memory without going through a struct?
If you were thinking of doing the shmat version of this,
1
2
int **arr = new int*[10];
for ( int i = 0 ; i < 10 ; i++ ) arr[i] = new int[100];


then the answer is no (or it's a world of pain).

The real problem comes in when your peer process calls shmat to get a pointer to arr, only to find out that it's been mapped to a different virtual address. This instantly renders all the arr[i] pointers in the second process as illegal addresses (they're only valid in the first process).

Picking your own shmaddr to pass to shmat would solve the problem, only to be replaced with how to choose a good shmaddr in the first place. If that fails, you're still SoL.

If you need variable sized 2D arrays, the simplest is to just allocate the single monolithic block of memory, then do your own row*cols+col manual subscripting on it.
Topic archived. No new replies allowed.