System V共享内存的分段错误

时间:2015-01-09 16:34:12

标签: c shared-memory strcpy

我试图理解当我尝试使用strcpy将某些字符复制到共享内存时,这个简单代码导致分段错误的原因:

#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <string.h>

int main()
{
    key_t key;
    int flag,id;
    char *buf;

    flag=IPC_CREAT|0600;
    if((key=ftok("myfile",12)) == -1 ) {
        perror("key");
        exit(2);
    }   
    printf("%X\n",key);

    if( (id=shmget(key,512,flag)) < 0) exit(1); 

    if( (buf=shmat(id,0,0)) < 0) exit(2);

    printf("PID %d, buf=%p\n",getpid(),buf);
    system("ipcs -m | grep 512");
    sleep(20);

    strcpy(buf,"Hello");
    sleep(100); 
    shmdt(buf);
    exit(0);
}

这就是我得到的:

C1A0DAB
PID 12063, buf=0xffffffff8bc78000
0x0c1a0dab 271941746  username      600        512        1
Segmentation fault (core dumped)

此外,该过程的pmap表明:

00007f778bc78000      4K rw-s-    [ shmid=0x10358072 ]

我猜指针buf出了点问题,但到目前为止我还不知道如何解决这个问题。

有什么想法吗?

3 个答案:

答案 0 :(得分:2)

请编译并启用所有警告(例如,至少-Wall代表gcc和clang。)

您缺少#include <sys/shm.h>,因此您的编译器会假定smhat返回一个int,而实际上它返回void*。如果int和void*的大小不匹配,则会出现问题。

添加包含,添加其他您正在丢失的内容,它应该可以正常工作。

答案 1 :(得分:1)

注意从编译器获得的警告。特别是,你得到:

file.c:22:5: warning: implicit declaration of function ‘shmat’ [-Wimplicit-function-declaration]
file.c:22:13: warning: assignment makes pointer from integer without a cast

它告诉你问题是什么 - 编译器假设shmat返回一个(32位)整数,实际上它返回一个(64位)指针。所以你失去了指针的前32位......

答案 2 :(得分:0)

此信息来自http://web.cse.ohio-state.edu/~babic/Sem.shmem.new.pdf    需要考虑:

重要的是: 未明确删除的信号量和共享内存留在系统中 在创建它们的进程终止后 甚至当用户注销时

自UNIX以来 它支持有限数量的那些资源 重要的是要确保所有创建 信号量和共享记忆是雷莫 在退出之前。

目录 / usr / class / cis660包括 是脚本文件 RSM .dat提供了删除所有方便的方法 信号量和所有共享记忆。

个人信号量或共享备忘录 可以使用UNIX命令删除ry ipcrm -s sem# 要么 ipcrm -m mem# ,分别是从UNIX命令获得sem#和mem# IPCS ,列出所有信号量和共享记忆