共享内存:分段错误内核转储 #包括 #包括 #包括 #包括 #包括 #包括 int main() { int shmid; char*viraddr; 字符缓冲区[BUFSIZ]; shmid=shmget(1234,BUFSIZ,0666 | IPC|u CREAT); viraddr=(char*)shmat(shmid,0,0); 而(1) { 放置(“输入一些文本:”); fgets(缓冲区、BUFSIZ、标准输入); strcat(viraddr,缓冲器); 如果(strncmp(缓冲区,“结束”,3)==0) 打破 } shmdt(viraddr); 出口(0); }
我正在学习共享记忆。我想实现两个进程之间的通信。当我运行此程序时,它总是指示此错误--共享内存:分段错误内核转储 #包括 #包括 #包括 #包括 #包括 #包括 int main() { int shmid; char*viraddr; 字符缓冲区[BUFSIZ]; shmid=shmget(1234,BUFSIZ,0666 | IPC|u CREAT); viraddr=(char*)shmat(shmid,0,0); 而(1) { 放置(“输入一些文本:”); fgets(缓冲区、BUFSIZ、标准输入); strcat(viraddr,缓冲器); 如果(strncmp(缓冲区,“结束”,3)==0) 打破 } shmdt(viraddr); 出口(0); },c,linux,memory,shared-memory,C,Linux,Memory,Shared Memory,我正在学习共享记忆。我想实现两个进程之间的通信。当我运行此程序时,它总是指示此错误--分段错误核心转储。有什么帮助吗?谢谢。这里viraddr和buffer的大小都相同。对于strcat(),建议dst大小至少比src大小大一个字节。viraddr应该有足够的空间来保存缓冲区数据,以避免缓冲区溢出。也许,有时内存分配返回FFFFF,然后抛出分段错误内核转储。原因是您没有足够的权限访问进程的内存 只需使用sudo编译和运行代码。比如说你有这些文件 shm1.c shm2.c 嘘 然后您的命令需要按
分段错误核心转储
。有什么帮助吗?谢谢。这里viraddr和buffer的大小都相同。对于strcat(),建议dst大小至少比src大小大一个字节。viraddr应该有足够的空间来保存缓冲区数据,以避免缓冲区溢出。也许,有时内存分配返回FFFFF
,然后抛出分段错误内核转储。原因是您没有足够的权限访问进程的内存
只需使用sudo编译和运行代码。比如说你有这些文件
shm1.c
shm2.c
嘘
然后您的命令需要按如下方式激发
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/shm.h>
int main()
{
int shmid;
char *viraddr;
char buffer[BUFSIZ];
shmid=shmget(1234,BUFSIZ,0666|IPC_CREAT);
viraddr=(char*)shmat(shmid, 0,0);
while(1)
{
puts("Enter some text:");
fgets(buffer,BUFSIZ,stdin);
strcat(viraddr,buffer);
if(strncmp(buffer,"end",3)==0)
break;
}
shmdt(viraddr);
exit(0);
}
如果您愿意在两个不同的终端上执行此操作,只需在终端1中启动sudo./s1
,在不同的终端2中启动sudo./s2
,对我来说很好。。。Fedora 20 64位,+valgrind…我认为您应该使用strcpy
而不是strcat
,因为您不知道viraddr
的内存中是否有垃圾。它为什么对dguncev有效可能是因为shmat
返回的地址中的内存恰好是0s。不,它有效是因为IPC_create
用于创建新段。。。并且,当创建新的共享内存段时,其内容将初始化为零值。请参见man 2 shmget
。可能viraddr为空。调用shmat()后可以打印它吗?完全正确。验证shmget
和shmat
成功。一点长度验证以确保不会溢出viraddr
,可能也会有很大的作用。这与此无关。创建新的共享内存段时,其大小等于BUFSIZ
的值,四舍五入为PAGE\u size
的倍数。除非共享内容超过了BUFSIZ
(四舍五入到最接近的页面大小
),否则这不适用。
sudo gcc shm1.c -o s1
sudo gcc shm2.c -o s2
sudo ./s1 &
sudo ./s2