通过共享内存和管道的 IPC 给出分段错误:C 中的 11
IPC through shared memory and pipe gives segmentation fault: 11 in C
我正在尝试在 parent 和 child 进程之间共享一个文件。 Parent 通过管道发送文件,然后 child 将该行写入共享内存,以便 parent 可以通过共享内存读取和打印文件。但是,我遇到了分段错误: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;
}
快速观察。
在以下代码中,您有一个未初始化为指向任何内容的 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] = '[=13=]'; // Terminate the string to the number of bytes read
sprintf(ptr_child_1, "%s", s);
ptr_child_1 += num;
}
我正在尝试在 parent 和 child 进程之间共享一个文件。 Parent 通过管道发送文件,然后 child 将该行写入共享内存,以便 parent 可以通过共享内存读取和打印文件。但是,我遇到了分段错误: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;
}
快速观察。
在以下代码中,您有一个未初始化为指向任何内容的 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] = '[=13=]'; // Terminate the string to the number of bytes read
sprintf(ptr_child_1, "%s", s);
ptr_child_1 += num;
}