通过共享内存和管道的 IPC 给出分段错误:C 中的 11
Posted
技术标签:
【中文标题】通过共享内存和管道的 IPC 给出分段错误:C 中的 11【英文标题】:IPC through shared memory and pipe gives segmentation fault: 11 in C 【发布时间】:2020-02-15 17:49:48 【问题描述】:我正在尝试在父进程和子进程之间共享文件。父级通过管道发送文件,子级将这些行写入共享内存,以便父级可以通过共享内存读取和打印文件。但是,我遇到了分段错误:11。此外,我做了类似下面的代码的事情,但那时我无法获得正确的内容,甚至每次调用都得到不同的结果。
我不确定增加指针部分。但是,最好多关注一下代码。
编辑:我将 char* 更正为 char[] 并且分段错误现在消失了。但是,每次运行我都会得到不同的结果,输出中会看到一些额外的字符。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <unistd.h>
#define SHM_NAME_1 "Child 1"
int main()
pid_t pid;
FILE *file;
char *infile = "in.txt";
pid = fork();
if(pid < 0)
fprintf(stderr, "Fork failed\n");
return 1;
if(pid > 0) // parent
file = fopen(infile, "r");
if(file == 0)
fprintf(stderr, "File failed\n");
return 1;
// close read end of pipe
mknod("FIFO", S_IFIFO | 0666, 0);
int fd = open("FIFO", O_WRONLY);
char str[300];
while(fgets(str, sizeof(str), file) > 0)
// write all lines of file
write(fd, str, strlen(str));
// close file and pipe
close(fd);
fclose(file);
// wait for child to write to shared memory
wait(NULL);
// open shared segment
int shm_first = shm_open(SHM_NAME_1, O_RDONLY, 0666);
if (shm_first == -1)
fprintf(stderr, "Failed: Shared Memory 1");
exit(-1);
// create memory pointer
void *ptr = mmap(0,4096, PROT_READ, MAP_SHARED, shm_first, 0);
if (ptr == MAP_FAILED)
printf("Map failed 1\n");
return -1;
// print out result and unlibk shared segment
fprintf(stdout, "Normal input: \n%s\n", ptr);
shm_unlink(SHM_NAME_1);
else // child
// create the shared segment for the first time
int shm_child_1 = shm_open(SHM_NAME_1, O_CREAT | O_RDWR, 0666);
// configure the size of the shared memory segment
ftruncate(shm_child_1,4096);
// map the pointer to the segment
void *ptr_child_1 = mmap(0,4096, PROT_READ | PROT_WRITE, MAP_SHARED, shm_child_1, 0);
if (ptr_child_1 == MAP_FAILED)
printf("Map failed in first child\n");
return -1;
mknod("FIFO", S_IFIFO | 0666, 0);
int fd = open("FIFO", O_RDONLY);
int num;
char s[300];
while((num = read(fd, s, sizeof(s)))> 0)
sprintf(ptr_child_1, "%s", s);
ptr_child_1 += num;
close(fd);
exit(0);
return 0;
【问题讨论】:
我认为 EOF 发生了一些事情 【参考方案1】:快速观察。
在以下代码中,您有一个未初始化为指向任何内容的 char 指针。这会导致 fgets 将从file
读取的内容复制到内存中的某个任意位置。
char *str;
while(fgets(str, 100, file) > 0)
既然缓冲区问题解决了,下面的表达式中的大括号也有问题
while((num = read(fd, s, sizeof(s)) > 0))
num
将是 1 或 0,而不是读取的字节数或 eof 的 0。这应该是
while((num = read(fd, s, sizeof(s))) > 0)
一旦读取了字节数,就需要将缓冲区归零。因为您使用的是 sprintf
,它期望 %s
的参数是一个以零结尾的字符串。
while((num = read(fd, s, sizeof(s)))> 0)
s[num] = '\0'; // Terminate the string to the number of bytes read
sprintf(ptr_child_1, "%s", s);
ptr_child_1 += num;
【讨论】:
是的,当我更改为 char 数组时,它可以工作。但是现在子进程只读取我文件的第一行,即使父进程写入了所有行。 嗯,我想我也想通了,但我不知道为什么我会在输出末尾得到额外的字符/ 顺便说一句。在客户端代码中读取 char *r 时遇到同样的问题。 哇,谢谢!我做了类似的事情,在父级的while循环结束时,我显式发送了eof。以上是关于通过共享内存和管道的 IPC 给出分段错误:C 中的 11的主要内容,如果未能解决你的问题,请参考以下文章