shmat返回分段错误(核心转储)

时间:2013-05-19 15:43:37

标签: c linux shared-memory

我试图写入共享内存但由于某些原因我调用shmat()和strcpy后我得到分段错误(核心转储)为什么会这样?

这是我的代码:

int fd,shmid;
key_t shmkey;
char *shm_add;
pid_t pid,pid1=0,pid2=0;

shmkey=ftok("shmdemo.c",'j');
if ( shmkey == (key_t)-1 )
 {
    printf("main: ftok() for shm failed\n");
    return -1;
}
shmid=shmget(shmkey, 50, 0666 | IPC_CREAT | IPC_EXCL);
if (shmid == -1)
{
    printf("main: shmget() failed\n");
    return -1;
}
shm_add=(char *)shmat(shmid,0,0);
if ( shm_add==NULL )
{
    printf("main: shmat() failed\n");
    return -1;
 }

strcpy(shm_add,"hello");

编辑:我在目录上有文件名shmdemo.c,shmget的错误说“文件存在”但是当我从目录中删除“shmdemo.c”时,一个新的错误来自ftok,说“不存在”这样的文件或目录“。

谢谢Asaf。

2 个答案:

答案 0 :(得分:2)

回答各种评论。当你打电话:

shmget(..., IPC_CREAT | IPC_EXCL);

您对标志的说法是:为此密钥创建共享内存段,确保已存在该密钥的共享内存段。

如果您只使用:

shmget(..., IPC_CREAT);

你说的是:如果共享内存段已经存在并使用此键,则将其返回; 否则为此密钥创建一个新密钥并返回该密钥。

通常,您可能不希望调用的第二个变体。并发是很难的,没有添加任何你自己的非确定性。 (即,只要让一堆协作进程中的任何一个首先创建共享内存;而不是指定“所有者”进程。)

使用第一次调用时,如果给定键上已存在共享内存段,则系统调用将失败并显示errnoEEXISTS。 SysV IPC具有持久性,因此在程序退出后,例如文件描述符,它们不会自动清理。 (事实上​​,它们更类似于临时文件。)

您应该使用shmctl(shmid, IPC_RMID, NULL);等内容在程序中清理它们。您还可以使用ipcs检查流浪的IPC对象,并使用ipcrmcleanipcs删除遗留的对象。

答案 1 :(得分:0)

尝试删除IPC_EXCL标记并检查程序。