【问题标题】:Why does this code give a segfault? Shared memory IPC SYSV为什么这段代码会出现段错误?共享内存 IPC SYSV
【发布时间】:2014-01-26 12:52:54
【问题描述】:

为什么这段代码会出现段错误?共享内存 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);

段错误

【问题讨论】:

  • 哪一行出现分段错误?
  • 没写,不过我觉得是4到7之间。
  • 检查shmgetshmat 的返回值是否有错误是一个好的开始。

标签: c segmentation-fault shared-memory


【解决方案1】:

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;
  }

【讨论】:

  • 我得到“shmat()失败”。为什么?
  • @user3062986:除了“失败”之外,它不是告诉你更多吗?
猜你喜欢
  • 2019-04-13
  • 2010-10-19
  • 2020-07-26
  • 2011-12-27
  • 1970-01-01
  • 1970-01-01
  • 2020-11-03
  • 2013-03-28
相关资源
最近更新 更多