How to shmget and shmat a double array in C?
I know 2D array can be weird in C, and with malloc, i would do something like this:
/* This is your 2D array. */
double** matrix;
/* The size dimensions of your 2D array. */
int numRows, numCols;
/* Used as indexes as in matrix[x][y]; */
int x, y;
/*
* Get values into numRows and numCols somehow.
*/
/* Allocate pointer memory for the first dimension of a matrix[][]; */
matrix = (double **) malloc(numCols * sizeof(double *));
if(NULL == matrix){free(matrix); printf("Memory allocation failed while allocating for matrix[].\n"); exit(-1);}
/* Allocate integer memory for the second dimension of a matrix[][]; */
for(x = 0; x < numCols; x++)
{
matrix[x] = (double *) malloc(numRows * sizeof(double));
if(NULL == matrix[x]){
free(matrix[开发者_运维问答x]); printf("Memory allocation failed while allocating for matrix[x][].\n");
exit(-1);
}
}
and the initialize, with 2 fors, the array. Now, I want to allocate space in shared memory to a **array, but I don't know if I can do this:
shmid2 = shmget(IPC_PRIVATE, numCols * sizeof (int*), IPC_CREAT | 0700);
my_array = (double**) shmat(shmid2, NULL, 0);
and then initialize it. Is this correct. If not, how can I do this the right way?
Thank you in advance
You can do this with a single contiguous shared memory segment. The trick is that the double
values themselves live in the shared memory, but your double *
row pointers can be just regular malloc
memory, since they're just an index into the shared memory:
double *matrix_data;
double **matrix;
int x;
shmid2 = shmget(IPC_PRIVATE, numRows * numCols * sizeof matrix_data[0], IPC_CREAT | 0700);
matrix_data = shmat(shmid2, NULL, 0);
matrix = malloc(numCols * sizeof matrix[0]);
for(x = 0; x < numCols; x++)
{
matrix[x] = matrix_data + x * numRows;
}
(Note that this allocates the index in column-major order, as your code does, which is unusual in C - row-major order is more common).
Separate programs sharing the shared memory segment each allocate their own index matrix
using malloc
- only the actual array is shared.
By the way, you can use the same method for a non-shared array, replacing the shared memory call with a plain malloc()
. This allows you to use a single allocation for the entire array, plus one for the index, whereas your code has one allocation per column.
I've done it! I will give and example with a struct other then a double array, but you get the point.
So, basically I want to allocate a **pixel, pixel_data (member of structure image_struct, here instantiated as image) in a segment of shared memory.
shmid2 = shmget(IPC_PRIVATE, image->width * sizeof (pixel*), IPC_CREAT | 0700);
image->pixel_data = (pixel**) shmat(shmid2, NULL, 0);
/* Allocate integer memory for the second dimension of **pixel_data; */
for (i = 0; i < image->width; i++) {
shmPixelId = shmget(IPC_PRIVATE, image->height * sizeof (pixel), IPC_CREAT | 0700);
image->pixel_data[i] = (pixel *) shmat(shmPixelId, NULL, 0);
if ( image->pixel_data[i]== NULL) {
shmdt(image->pixel_data[i]);
printf("Sh_Memory allocation failed while allocating for pixel_data[i][].\n");
exit(-1);
}
}
My structures:
typedef struct pixel_t {
byte red;
byte green;
byte blue;
}pixel;
typedef struct {
int width;
int height;
pixel **pixel_data;
} image_struct;
I follow the same code I did to malloc a dimensional array, but instead I used shared memory.
I would not do it this way, even with malloc because of memory fragmentation once the array becomes big. And with shmget you will get an issue also with fd's (one fd per shmget is used).
I would recommend doing it this way (uncompiled since no C compiler is close)
double* matrix = malloc( sizeof(double)*numrows*numcols);
double value = matrix[actrow*numrows+actcol];
free ( matrix);
You have to remember numrows throughout your app, but this way it is much more clean from the memory side. Also, now it is one big chunk and you can do the same thing with shmget/shmat.
精彩评论