C 指向共享内存中数组的共享指针,指针不';你似乎不愿意分享吗?

C 指向共享内存中数组的共享指针,指针不';你似乎不愿意分享吗?,c,linux,fork,shared-memory,C,Linux,Fork,Shared Memory,我在共享内存中有一个数组。我想使用一个指针来迭代这个数组,这个数组也是用来共享的。以下是我尝试过的: /* initialize color sequence in shared memory */ shmkey = ftok("/dev/null",3); /* executable name and a random number */ shmid = shmget(shmkey, sizeof(char), 0700 | IPC_CREAT); if(s

我在共享内存中有一个数组。我想使用一个指针来迭代这个数组,这个数组也是用来共享的。以下是我尝试过的:

    /* initialize color sequence in shared memory */
    shmkey = ftok("/dev/null",3);   /* executable name and a random number */
    shmid = shmget(shmkey, sizeof(char), 0700 | IPC_CREAT);
    if(shmid < 0){      /* shared memory error check */
        perror("shmget\n"); 
        exit(1);
    }
    queue = (char*) shmat(shmid, NULL, 0);  /* shared memory part of colorSequence */
    printf("queue allocated.\n");

    /* initialize color sequence pointer in shared memory */
    shmkey = ftok("/dev/null//",61);    /* executable name and a random number */
    shmid = shmget(shmkey, sizeof(char), 0700 | IPC_CREAT);
    if(shmid < 0){      /* shared memory error check */
        perror("shmget\n"); 
        exit(1);
    }
    p = (char*) shmat(shmid, NULL, 0);  /* pointer to queue in shared memory */
    printf("queue pointer allocated.\n");
    p = &queue[0];
然而,输出是(队列的内容如下:rbg…):

我不明白为什么我会得到这些结果,即使指针应该是共享的。你能帮我修一下吗?谢谢

编辑

当我尝试在父进程中将p点的值更改为时,从子进程打印时效果是可见的。但是,递增指针不起作用。

您实际上有两个问题,但操作系统缓解了其中一个问题

第一个问题是,您说您的共享内存大小为1(
sizeof(char)
)。当操作系统将其四舍五入到页面大小时,这一点会得到缓解

第二个问题是:

p = (char*) shmat(shmid, NULL, 0);  /* pointer to queue in shared memory */

p = &queue[0];
这里您可以从共享内存中获得
p
,您可以用另一个指针覆盖该指针


然而,这是一个有争议的问题,原因有两个:第一个是我评论的问题。第二个问题是,即使您不覆盖指针
p
,它仍然是进程的“本地”指针,因此这样做(例如
p++
)不会更改共享内存中的副本,因为实际指针没有共享。如果你真的想在共享内存中有一个指针,你就必须
p
成为指向指针的指针,必须执行
(*p)+
来增加本地和共享内存中的指针。

你可以共享内存,但不能共享指针。请记住,(虚拟)内存映射对于每个进程都是唯一的。一个进程中指向共享内存的指针可能(而且很可能会)与另一个进程中指向同一共享内存的指针不同。这是否意味着我必须将
p
定义为
char**
并分配共享内存?然后我做
(*p)=&queue[0]
。是这样吗?如果没有,我应该如何继续?我不确定将内存地址放入共享内存段以供其他进程使用是否安全。记忆是以奇怪的方式映射的(至少对我来说),这似乎不是一个应该依赖的保证。您至少应该将其抽象为内存空间中的偏移量,然后将其用于每个副本中的本地指针。但也许你说的没问题——对我来说仍然很可怕。@Volkanİlbeyli是的,如果指针确实可以共享,你应该这样做。如果第二个进程是第一个进程的子进程,并且第一个进程在分叉之前创建并附加到共享内存,那么第二个进程的共享内存段与第一个进程的地址相同。使用SystemV IPC,您还可以请求共享内存段位于特定地址;如果所有进程都请求相同的地址,但没有一个进程被拒绝,则可以使用指向不同进程中共享内存的指针。否则(这样做总是安全的),您应该记录数组等的偏移量或索引号,并在不同的过程中使用它们。
Parent printing           *p=R, p=0x7f5c77837000
Parnet printing after++   p=B, p=0x7f5c77837002
   Child printing         *p=R, p=0x7f5c77837000
   Child printing after++ p=G, p=0x7f5c77837001
p = (char*) shmat(shmid, NULL, 0);  /* pointer to queue in shared memory */

p = &queue[0];