2012-04-18 78 views
1

我正在嘗試編寫共享結構類型的代碼,但在嘗試寫入共享內存中的結構成員時出現分段錯誤,共享內存爲父母與子女之間的過程。正如我在代碼中顯示的那樣,我現在只是嘗試訪問struct成員,所以我可以稍後使用信號量進行同步。訪問共享內存中的結構成員「in C」

Thanx提前。

typedef struct file 
{ 
    char *shmPtr; 
} file_entry; 

int main (void) 
{ 

    int shmid; 
    int n; 
    file_entry *entries; 

    if (fork() == 0) { 
     /*wait for a while*/ 

     if ((shmid = shmget(20441, sizeof(file_entry), 0666)) == -1) { 
      printf("shmget"); 
      exit(2); 
     } 

     entries = (file_entry*) shmat(shmid, 0, 0); 
     if (entries->shmPtr == (char *) -1) { 
      printf("problem2"); 
      exit(2); 
     } 

     printf("\nChild Reading ....\n\n"); 
     printf("%s\n", entries->shmPtr[0]); 
     printf("%s\n", entries->shmPtr[1]); 
     putchar('\n'); 
     printf("\nDone\n\n"); 
    } else { 
     if ((shmid = shmget(20441, sizeof(file_entry), IPC_CREAT | 0666)) == -1) { 
      printf("problem3"); 
      exit(2); 
     } 

     entries = (file_entry *) shmat(shmid, 0, 0); 
     if (entries->shmPtr == (char *) -1) { 
      printf("problem4"); 
      exit(2); 
     } 
     printf("done attachment"); /*the parent prints this statment, then segmentation fault*/ 

     entries->shmPtr[0]='a'; 
     entries->shmPtr[1]='b'; 
     putchar('\n'); 

     wait(); 
     shmdt(&shmid); 
    } 
    exit(0); 
} 

回答

1

shmat指針返回到所述共享存儲器區域。在您的代碼中,在撥打shmat後,entries指向共享區域。然後,您將該共享區域的前幾個字節視爲指向char的指針(shmPtr)。 shmPtr的值未初始化,並指向某個隨機位置。然後,您嘗試寫入並獲得段錯誤。

編輯:

正如理查德建議,你可以擺脫結構和只使用一個char *。但是,我猜你正在使用struct的原因,而不僅僅是char *是你計劃在將來爲結構添加一些額外的字段。如果是這樣的話,你可以使用一個靈活數組成員

typedef struct file 
{ 
    int flag; 
    int blah; 
    char shmPtr[]; 
} file_entry; 

和分配變得

shmget(20441, sizeof(file_entry) + bufsize, IPC_CREAT | 0666) 

當然,如果緩衝區大小是固定的,你可以只硬編碼:

typedef struct file 
{ 
    int flag; 
    int blah; 
    char shmPtr[BUFSIZE]; 
} file_entry; 

/* ... */ 
shmget(20441, sizeof(file_entry), IPC_CREAT | 0666) 
+0

我會詳細說明,並說file_entry應該是char *的typedef。 – 2012-04-18 19:18:45

+0

@ g.inozemtsev非常感謝你,解決了我的問題。 – CodeRed 2012-04-18 20:02:50