我可以直接将共享内存的地址分配给指针吗?

时间:2018-09-20 07:27:29

标签: c arrays pointers struct shared-memory

我正在尝试为IPC创建共享内存。我想将具有动态2D数组的结构放入共享内存中。这是结构。

/* struct with 2 2D arrays. */
struct _test {
    uint16_t **A;
    uint16_t **B;
} test;

我知道双指针实际上不是2D数组,我应该像int (*ptr)[3]那样使用指针进行数组,但是问题是我只能得到运行时的2D数组。因此,我必须以这种方式(至少我所知道的)声明2D数组。

然后我在运行时计算这两个数组的大小,说它们都是2x2数组,占用16个字节(uint16_t为2个字节)。所以我这样做了:

#include <sys/ipc.h>
#include <sys/shm.h>
#include <memory.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
    size_t size = 16;  //size of two uint16_t 2D arrays.
    key_t key;
    key = ftok("dev/null", 1);
    int s_shm_id = shmget(key, size, IPC_CREAT|0600);  //get 16 bytes of shared memory.
    test *shm = (test*)shmat(s_shm_id,(const void*)0,0);  //attach it.

    //I want pointers in this struct to point at shared memory.
    test *ptr = malloc(sizeof(test));  

    //Array A starts at the beginning of shared memory.
    ptr -> A = (uint16_t **)shm;  //My main confusion is here. Is this right?
    int i;
    for(i=0; i<2; i++)
            ptr->A[i] =(uint16_t *)((uint16_t *)ptr->A + i*2);

    //Array B starts right after A.
    ptr -> B = ptr -> A[i-1] + 2;
    for(i=0; i<2; i++)
            ptr -> B[i] = (uint16_t *)((uint16_t *)ptr->B + i*2);
  }

我了解这基本上是错误的,我遇到了段错误,但是如何?指针需要指向的地址,因为我已经创建了一个空间(使用shmget),为什么不能创建指向该地址的指针呢?感谢您提前反馈!

1 个答案:

答案 0 :(得分:1)

所追求的是“锯齿状”或“分散”阵列,而不是“线性”阵列。分散的2D数组实际上不是一个数组,而是1 + N数组,其中N是您要寻找的2D矩阵的维数。

您显示的代码未在“ 1 + N”内分配此1数组。

假设您成功分配了足够的内存来容纳两个N的{​​{1}}维,即uint16_t个字节的2D数组,那么准备访问该内存的代码可能看起来像这(为了便于阅读而忽略了错误检查):

2 * N*N * sizeof (uint16_t)

void * p = ... /* Allocate memory here; does not necessarily needs to be SHM. */ uint16_t ** A = malloc(N * sizeof *A); for (size_t i = 0; i < N; ++i) { A[i] = ((uint16_t*) p) + i*N; } uint16_t ** B = malloc(N * sizeof *B); for (size_t i = N; i < 2*N; ++i) { B[i - N] = ((uint16_t*) p) + i*N; } /* Access A[0 .. N-1][0 .. N-1] and B[0 .. N-1][0 .. N-1] here ... */ A放在动态分配的B内,作为练习。

直接访问数组的元素:struct访问第1个数组的第1行的第1个元素。

为清楚起见,A[0][0]数组使用相同的代码

NxM