我试图写入共享内存但由于某些原因我调用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。
答案 0 :(得分:2)
回答各种评论。当你打电话:
shmget(..., IPC_CREAT | IPC_EXCL);
您对标志的说法是:为此密钥创建新共享内存段,和确保已存在该密钥的共享内存段。
如果您只使用:
shmget(..., IPC_CREAT);
你说的是:如果共享内存段已经存在并使用此键,则将其返回; 否则为此密钥创建一个新密钥并返回该密钥。
通常,您可能不希望调用的第二个变体。并发是很难的,没有添加任何你自己的非确定性。 (即,只要让一堆协作进程中的任何一个首先创建共享内存;而不是指定“所有者”进程。)
使用第一次调用时,如果给定键上已存在共享内存段,则系统调用将失败并显示errno
值EEXISTS
。 SysV IPC具有持久性,因此在程序退出后,例如文件描述符,它们不会自动清理。 (事实上,它们更类似于临时文件。)
您应该使用shmctl(shmid, IPC_RMID, NULL);
等内容在程序中清理它们。您还可以使用ipcs
检查流浪的IPC对象,并使用ipcrm
或cleanipcs
删除遗留的对象。
答案 1 :(得分:0)
尝试删除IPC_EXCL
标记并检查程序。