C 如何在同一共享内存段中正确使用多个变量

C 如何在同一共享内存段中正确使用多个变量,c,shared-memory,C,Shared Memory,我试图在同一内存段中有2个整数。我的代码如下: int main() { int *a; int *b; int id; id = shmget(IPC_PRIVATE,10,0666); a = (int *) shmat(id, (void*)0, 0); b = (int *) shmat(id, (void*)0, 0); *a = 5; *b = 10; printf("%d\n",*a); printf("%d\n

我试图在同一内存段中有2个整数。我的代码如下:

int main()
{
  int *a;
  int *b;
  int id;
  id = shmget(IPC_PRIVATE,10,0666);
  a = (int *) shmat(id, (void*)0, 0);
  b = (int *) shmat(id, (void*)0, 0);
  *a = 5;
  *b = 10;
  printf("%d\n",*a);
  printf("%d\n",*b);
}
这个打印10次。谁能解释一下为什么会发生这种情况以及如何解决

额外问题:如果我使用char*而不是int,那么是否有必要执行malloc(sizeof(char)*10)或shmat调用以某种方式执行此任务


提前谢谢

首先,如果可能,您总是希望使用
malloc
而不是共享内存。 即使在进行IPC时,简单管道通常也更有效

回到你的问题,这里是对你的代码的一些解释

int main()
{
  int *a;
  int *b;
  int id;

  /* 'shmget' creates a shared memory segments of size 10,
     basically reserving 10 bytes of RAM/Swap. This memory is not 
     accessible in your virtual memory yet */   
  id = shmget(IPC_PRIVATE,10,0666);

  /* `shmat` maps the shared memory from above and makes it accessible in
     your virtual memory. `a` points to the beginning of the memory segment */ 
  a = (int *) shmat(id, (void*)0, 0);

  /* Here we map the same shared memory again into a different place in the
     virtual memory. But even if `a` and `b` points to different memory
     addresses, those addresses are backed by the same segment in RAM/Swap */  
  b = (int *) shmat(id, (void*)0, 0);

  *a = 5;
  *b = 10; /* because `*a` and `*b` are backed by the same RAM/Swap, */ 
           /* this will allso overwrite `*a`                        */

  printf("%d\n",*a);
  printf("%d\n",*b);
}
要解决这个问题,基本上有两种选择。它们都有两个共享内存段,一个用于
a
,另一个用于
b
。或者使一个段足够大,以容纳
a
b
指向段中的不同位置:

第一个解决方案:

/* This uses two segments */
int *a;
int *b;
int id1;
int id2;
id1 = shmget(IPC_PRIVATE,sizeof(int),0666);
id2 = shmget(IPC_PRIVATE,sizeof(int),0666);
a = (int *) shmat(id1, (void*)0, 0);
b = (int *) shmat(id2, (void*)0, 0);
/* This uses one segments */
int *a;
int *b;
int id;
/* Allocate enough memory for 2 int */
id = shmget(IPC_PRIVATE, 2*sizeof(int), 0666);
/* Map that memory into virtual memory space */
a = (int *) shmat(id, (void*)0, 0);
/* `a` points to the first int in a sequence of 2 ints, let `b` point to 
   the next one. */
b = a + 1;
第二种解决方案:

/* This uses two segments */
int *a;
int *b;
int id1;
int id2;
id1 = shmget(IPC_PRIVATE,sizeof(int),0666);
id2 = shmget(IPC_PRIVATE,sizeof(int),0666);
a = (int *) shmat(id1, (void*)0, 0);
b = (int *) shmat(id2, (void*)0, 0);
/* This uses one segments */
int *a;
int *b;
int id;
/* Allocate enough memory for 2 int */
id = shmget(IPC_PRIVATE, 2*sizeof(int), 0666);
/* Map that memory into virtual memory space */
a = (int *) shmat(id, (void*)0, 0);
/* `a` points to the first int in a sequence of 2 ints, let `b` point to 
   the next one. */
b = a + 1;
和往常一样,为了简洁起见,这段代码省略了错误检查。添加错误检查留给读者作为练习


对于额外的问题,无论是
malloc
还是任何共享内存函数都不关心您将在分配的内存中存储什么。他们只是给你一系列的
char
。你的工作是计算你需要多少字符。(顺便说一句,
sizeof(char)
始终为1)

参考,所有IPC示例都是自然给出的,除非您首先对虚拟内存有了基本的了解,否则这可能没有任何意义。非常感谢!如果a是整数,b是字符呢?第二种解决方案有效吗?@PanD22,在分配的内存中混合数据类型是完全可能的。您只需正确计算偏移量。最简单的方法是将
int
char
放在结构中,并为该结构分配足够的内存。