System V 共享内存的分段错误

Segmentation fault with System V shared memory

我试图理解为什么当我尝试使用 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 但我目前还不知道如何更正。

有什么想法吗?

请在启用所有警告的情况下进行编译(例如,对于 gcc 和 clang 至少 -Wall)。

您缺少 #include <sys/shm.h>,因此您的编译器假定 smhat returns 是一个整数,而实际上它是 returns void*。如果 int 的大小和 void* 不匹配,你就有问题了。

添加包括在内的内容,同时添加您遗漏的其他内容,它应该可以工作。

注意编译器发出的警告。特别是,您得到:

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 returns 一个(32 位)整数,而实际上它 returns 一个(64-位)指针。所以你丢失了指针的前 32 位...

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

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

自 UNIX 支持数量有限的这些资源,它是 重要的是要确保所有创建 信号量和共享内存是remo 在注销之前。

目录 /usr/class/cis660包括 s 脚本文件 rsm .dat 提供方便的方式来删除所有 一次信号量和所有共享内存。

个人信号量或共享备忘录 可以使用 UNIX 命令删除 ry ipcrm –s sem# 要么 ipcrm –m 内存# , 分别是从 UNIX 命令获得的 sem# 和 mem# 工控机 ,其中列出了所有信号量和共享内存