2012-04-18 79 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