为什么这段代码会出现段错误?共享内存IPC SYSV

时间:2014-01-26 12:52:54

标签: c segmentation-fault shared-memory

为什么此代码会出现段错误?共享内存IPC SYSV。

int * addr;
int shmid = shmget(0xABC, 10*sizeof(int), IPC_CREAT);

addr = (int*) shmat(shmid, NULL, 0);

for(i = 0; i < 10; ++i){
    addr[i] = (int)i*i;
}

shmdt(addr);
  

段错误

1 个答案:

答案 0 :(得分:0)

错误时

shmat()会返回(void *) -1

您的代码不会对此进行测试。因此,如果shmget()失败,代码会尝试取消引用(void *) -1

addr[0] = ...

肯定会调用未定义的行为。

shmat()可能失败,因为代码未指定对shmget()调用所请求的内存段的访问权限。

如果你想从拥有过程写入它,适当的权利是

  

S_IWUSR 00200用户具有写入权限

(请man 2 open查看shmget()可能为记忆段请求设置的完整访问权限。


作为一般建议:始终测试相关的系统调用以获得结果。将所有此类系统调用视为“相关”,如果系统调用失败,则返回可能未定义或不可用的值。

要在显示的代码的特定情况下执行此操作,您需要修改代码,如下所示:

  int shmid = shmget(0xABC, 10*sizeof(int), IPC_CREAT | S_IWUSR);
  if (-1 == shmid)
  {
    perror("shmget() failed");
    return EXIT_FAILURE;
  }

  int * addr = (int*) shmat(shmid, NULL, 0);
  if (((void *) -1) == addr)
  {
    perror("shmat() failed");
    return EXIT_FAILURE;
  }

  for(size_t i = 0; i < 10; ++i) 
  {
    addr[i] = (int)i*i;
  }

  if (-1 == shmdt(addr))
  {
    perror("shmdt() failed");
    return EXIT_FAILURE;
  }