Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C - 2D Dynamic Array (Double Pointer) - Shared Memory

I've got 2 processes (Client and Server) that are communicating through shared memory.

I need to create a 2D Array that is Dynamic (based on parameters). The array is stored in a struct and then written to the shared segment.

I can write the array to the shared memory, but cannot retrieve it from the other process.

Client Code:

struct shared_use_st {
    int     written_by_you;
    int     **PID_PRI_array;
};
            /* Prepare Dynamic 2D array */
        data_store = malloc(/*ROWS*/ 5 * sizeof(int*));
        for(i=0;i<5; i++)
            data_store[i] = malloc(/*COLS*/ 2 * sizeof(int));


        /* Prepare Dynamic 2D array - Shared Memory Seg */
        shared_stuff->PID_PRI_array = malloc(/*ROWS*/ 5 * sizeof(int*));
        for(i=0;i<5; i++)
            shared_stuff->PID_PRI_array[i] = malloc(/*COLS*/ 2 * sizeof(int));


        /* Write PID and PRI to data_store array */
        data_store[0][0] = pid;
        data_store[0][1] = 1;

        data_store[1][0] = 12345;
        data_store[1][1] = 2;

        data_store[2][0] = 12346;
        data_store[2][1] = 3;

        data_store[3][0] = 12347;
        data_store[3][1] = 4;   

        data_store[4][0] = 12348;
        data_store[4][1] = 5;   

            for(i=0;i<5;i++){
                for(x=0;x<=1;x++){
                    shared_stuff->PID_PRI_array[i][x] = data_store[i][x];
                }
            }

Server Code:

    for(i=0;i<5;i++){
    printf("PID: %d, PRI:%d\n", shared_stuff->PID_PRI_array[i][0], shared_stuff->PID_PRI_array[i][1]);              
}

I get a "Segmentation Fault" error.

Thanks.

like image 200
Jake Evans Avatar asked Feb 26 '13 21:02

Jake Evans


People also ask

How to allocate memory for 2 d array in C?

A 2D array can be dynamically allocated in C using a single pointer. This means that a memory block of size row*column*dataTypeSize is allocated using malloc and pointer arithmetic can be used to access the matrix elements.

How to dynamically allocate memory for array of pointers in C?

Dynamically allocating an array of M pointers Dynamically allocating an array of pointers follows the same rule as arrays of any type: type *p; p = malloc(m* sizeof *p); In this case type is float * so the code is: float **p; p = malloc(m * sizeof *p);


1 Answers

Even if your shared_stuff object is in shared memory, you are not writing the array to shared memory. You are allocating space with malloc, writing data to that space, and then putting pointers to that space into shared_stuff. malloc allocates space within the current process‘ normal address space, not in a shared memory segment you have created. You need to write the array contents to the shared memory.

Presuming there is enough space for the array within the shared memory segment, you will have to manage the addresses yourself, not using malloc. (If there is not enough space, you must make the shared memory segment larger or convey the information in pieces over time.)

You can place a variable-length array within the shared memory segment as follows.

First, define a structure that contains all the “management” information you need, such as the array sizes:

struct StuffStruct
{
    size_t NumberOfRows, NumberOfColumns;
    … Other information as desired.
};

Create a pointer to that structure and set it to point to the shared memory segment:

struct StuffStruct *Stuff = shm;    // shm contains the address from shmat, performed previously.

Create a pointer to an array with the desired number of columns and set it to point into the shared memory segment after the initial structure:

int (*data_store)[NumberOfColumns] = (int (*)[NumberOfColumns]) ((char *) Stuff + sizeof *Stuff);

(Note for C purists: Yes, the C standard does not guarantee what happens when you do pointer arithmetic like this. However, any implementation providing shared memory support must provide support for this sort of pointer arithmetic.)

Note that sizeof *Stuff + NumberOfRows * NumberOfColumns * size(int) must be no greater than the size of the shared memory segment. Otherwise you will overrun the shared memory segment in the next step.

For the next step, fill the array with data: Assign values to the elements of data_store as for a normal two-dimensional array.

In the server, set Stuff the same way. Then, after the client has written the shared memory segment, read the numbers of rows and columns from Stuff. Then set data_store the same way. Then read from data_store.

like image 145
Eric Postpischil Avatar answered Sep 20 '22 02:09

Eric Postpischil