Your problem is in a – (your ?) – misunderstanding of the difference of a true 2D array, and a pointer→pointer→value indirection.
When you define a int **a
this is interpreted as a pointer to another pointer, that then reference an int
. Assigning a pointer obtained from an allocation function like malloc
or shmat
to such a double pointer, then as far as the semantics of C go, it expects this allocation of memory contain further pointers. So if you do a double dereference, and there's not a valid pointer there, it will fall flat on its face.
This misunderstanding is furthered by the fact, that in C you can validly write int a[X][Y];
and dereference it with a[i][j]
. The key insight to understand this is, that the first "half", i.e. that with a array defined like that, a[i]…
decays into a int*
pointer, that points toward the 0th element in the i
"column". The other half …[j]
then dereferences this implicitly "appearing" pointer.
Multidimensional arrays in C are deceiving and I strongly discourage using them like that. Also you'll have a hard time to properly implement specific padding and row alignments with them, without jumping some really annoying arithmetic.
It's easier by far, to just write down the calculations explicitly, with the added benefit of having precise control of padding and alignment.
Suppose we want to create a 2D array of int
, that shall be aligned to the sizes of long long
size_t const array_height = ...;
size_t const array_width = ...;
size_t const alignment = sizeof(long long);
size_t const row_size = array_width * sizeof(int);
size_t const row_stride =
alignment * ((row_size + alignment-1) / alignment);
size_t const array_size = array_height * row_stride;
int const shm_id = shmget(KEYSM, array_size, IPC_CREAT | 0666);
if( 0 > shm_id ){
perror("shmget");
exit(-1);
}
int *const array = shmat(shm_id, NULL, 0);
if( (void*)-1 == array ){
perror("shmat");
exit(-1);
}
for(size_t j = 0; j < array_height; ++j){
int *const row = array + j * row_stride;
for(size_t i = 0; i < array_width; ++i){
row[i] = (i % 2) ? -1 : 0;
}
}