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

C 我可以直接将共享内存的地址分配给指针吗?,c,arrays,pointers,struct,shared-memory,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数组(至少是我所知道的) 然后我在运行时计算这两个数组的大小,假设它们

我正在尝试为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);
  }
#包括
#包括
#包括
#包括
#包括
#包括
int main()
{
size\u t size=16;//两个uint16\u t 2D数组的大小。
钥匙(t)钥匙;;
key=ftok(“dev/null”,1);
int s_shm_id=shmget(key,size,IPC_CREAT | 0600);//获取16字节的共享内存。
test*shm=(test*)shmat(s_shm_id,(const void*)0,0);//附加它。
//我希望此结构中的指针指向共享内存。
测试*ptr=malloc(sizeof(测试));
//数组A从共享内存的开头开始。
ptr->A=(uint16\u t**)shm;//我的主要困惑在这里。对吗?
int i;
对于(i=0;iA[i]=(uint16_t*)((uint16_t*)ptr->A+i*2);
//数组B在A之后开始。
ptr->B=ptr->A[i-1]+2;
对于(i=0;ib[i]=(uint16_t*)((uint16_t*)ptr->B+i*2);
}
我知道这基本上是错误的,我得到了segfault,但是怎么做呢?指针需要的是指向的地址,因为我已经创建了一个空间(使用shmget),为什么我不能让指针指向它呢?感谢您提前反馈!

您想要的是“锯齿”或“分散”数组,而不是“线性”数组数组。一个分散的二维数组实际上不是一个数组,而是1+N个数组,其中N是您要查找的二维矩阵的维数

显示分配给“1+N”内的1数组的未命中数的代码

假设您成功地分配了足够的内存来容纳两个维度
N
uint16\u t
的二维数组,即
2*N*N*sizeof(uint16\u t)
字节,那么准备访问此内存的代码可能如下所示(为可读性而忽略了错误检查):


test*ptr=malloc(sizeof(*test));
就是您想要的,因为
sizeof(test)
就像
sizeof(void*)
这是一种指针类型,而不是实际的结构类型什么是
测试
?是键入定义结构还是忘记在此处输入关键字?@27Blend请在问题中添加相关信息,而不是commenting@TheophileDano请原谅,但你写的不正确。在问题的上下文中,假设C++。piler
sizeof(test)
返回了结构的大小
struct test
。在C语言中,显示的代码甚至不会编译。real是否也没有包含任何头?它是
A[i]=((uint16_t*)p)+i*N;
?@27Blend:当然可以。修复:像个符咒一样工作。谢谢你,先生。但仍然不明白我的代码为什么不工作。区别在于我直接将a指向一个现有地址(由
malloc
shmget
创建)与其使用
malloc
的返回值,但既然这两个地址都被分配了,为什么会有那么大的影响?@27Blend:拿一张纸,用图形化的方式描述我的方法是如何工作的。然后对你的方法做同样的事情。看到区别并变得开明!:-)当然应该是
B[i-N]
。还是我遗漏了一些明显的东西?
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 ... */
uint16_t ** A = malloc(N * sizeof *A);
for (size_t i = 0; i < N; ++i)
{
  A[i] = ((uint16_t*) p) + i*M;
}

uint16_t ** B = malloc(N * sizeof *B);
for (size_t i = N; i < 2*N; ++i)
{
  B[i - N] = ((uint16_t*) p) + i*M;
}