2011-06-13 77 views
0

我想创建一个使用“shmget”在父进程和子进程之间共享的结构数组。我遵循教授的模板,但他没有包含结构和数组(共享内存只存储了一个int)。下面的代码编译没有警告,但返回“0”作为输出,我期待看到“一个10”。我究竟做错了什么?共享内存中的两个进程的结构数组

此外,当我尝试在子进程内声明新变量时,我遇到了麻烦,我已经看到了其他示例,它在哪里工作,但我不知道为什么我每次都必须在fork之前声明它们。

typedef struct { 
    char character; 
    int number; 
} item; 

int main(int argc, char *argv[]) 
{ 
    int mem_id; 

    mem_id = shmget(IPC_PRIVATE, 10*sizeof(item), SHM_R | SHM_W); 
    item * x; 
    item * y; 
    item * list[10]; 

    switch(fork()) 
    { 
     case -1: 
      perror("Bad fork()"); exit(1); 
     case 0: 
      *list = shmat(mem_id, NULL, 0); 
      if ((int *) list == (int *) -1) 
      {perror("Child cannot attach"); exit(1);}   

      x->character = 'a'; 
      x->number = 10; 

      list[0] = x; 

      shmdt(list); 
      exit(0); 
     default: 
      *list = shmat(mem_id, NULL, 0); 
      if ((int *) list == (int *) -1) 
      {perror("Child cannot attach"); exit(1);} 

      wait((int *)0); 
      y = list[0]; 
      shmdt(list); 

      printf("%c %d\n", y->character, y->number); 

      if (shmctl(mem_id, IPC_RMID, 0) <0) 
       { perror("cannot remove shared memory"); exit(1);} 

      return 0; 
    } 
    return 0; 
} 
+2

在我看来就像你从来没有初始化'x' – Nemo 2011-06-13 02:20:09

+1

如果你只需要父母和孩子之间的交流,不要用'丑陋打扰shmat“等。只需在'fork'之前使用带有'MAP_SHARED'的'mmap',映射区域将在父和子之间共享。最重要的是,当你退出时,你不必担心清理它。 – 2011-06-13 02:40:54

+0

你所有的'item'都是指针。您也从不初始化它们,这意味着您正在更改未知位置的数据。 – ughoavgfhw 2011-06-13 04:25:34

回答

1

我很惊讶,你没有段错误,因为:

  1. 你不初始化X作为尼莫指出
  2. 你的阵列“名单”,实际上是一个指针数组项目而不是一个Items数组。
  3. 最重要的是。在y中打印出值之前,先分离共享内存。

的代码应该是这样的:

typedef struct { 
    char character; 
    int number; 
} item; 

int main(int argc, char *argv[]) 
{ 
    int mem_id; 

    mem_id = shmget(IPC_PRIVATE, 10*sizeof(item), SHM_R | SHM_W); 
    item *x; 
    item *y; 
    item *list; 

    switch(fork()) 
    { 
    case -1: 
     perror("Bad fork()"); exit(1); 
    case 0: 
     list = (item *)shmat(mem_id, NULL, 0); 
     if ((void *) -1 == (void *)list) 
     { 
      perror("Child cannot attach"); exit(1); 
     } 
     x = list; 
     x->character = 'a'; 
     x->number = 10; 

     shmdt(list); // No need for this 
     exit(0); 
    default: 
     list = (item *)shmat(mem_id, NULL, 0); 
     if ((void *) list == (void *) -1) 
     { 
      perror("Child cannot attach"); exit(1); 
     } 

     wait((int *)0); 
     y = list; 
     printf("%c %d\n", y->character, y->number); 

     shmdt(list); 

     if (shmctl(mem_id, IPC_RMID, 0) <0) 
      { perror("cannot remove shared memory"); exit(1);} 

     return 0; 
    } 
    return 0; 
}