2011-06-13 84 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; 
}