C 分段故障-如何从管道中写入和读取链表
我有一个整数数组,我必须确定在哪些索引上可以使用p进程找到给定的值。我拆分了向量,这样每个进程都可以在子向量中搜索该值,并在管道上写入索引。一个进程可以在多个位置上找到该值,我使用一个简单的链表来存储每个进程的索引。在那之后,我在管道上写字。我的问题是,读取是部分的,我得到了分段错误,因为列表的大小比我声明的要大。我怎样才能工作呢C 分段故障-如何从管道中写入和读取链表,c,linux,list,C,Linux,List,我有一个整数数组,我必须确定在哪些索引上可以使用p进程找到给定的值。我拆分了向量,这样每个进程都可以在子向量中搜索该值,并在管道上写入索引。一个进程可以在多个位置上找到该值,我使用一个简单的链表来存储每个进程的索引。在那之后,我在管道上写字。我的问题是,读取是部分的,我得到了分段错误,因为列表的大小比我声明的要大。我怎样才能工作呢 struct Node; typedef struct Node{ int val; struct Node *next; }Node; static
struct Node;
typedef struct Node{
int val;
struct Node *next;
}Node;
static int elementsList[] = { 1,2,3,4,5,6,7,8,3,10,11,12,3,14,15,16,17,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,
1,2,3,4,5,6,7,8,9,3,11,12,13,14,3,16,17,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,3 };
//method called by a process to check for the value in a subvector
void getPosition(int elemList[],int start,int step, int size, int value,int wPipe ){
Node *first = NULL;
Node *current;
Node *temp;
int i;
for(i = start; i < size ; i += step){
if(value == elemList[i]){
current = (Node*) malloc (sizeof(Node));
current->val = i;
if(first == NULL){
first = current;
first->next = NULL;
}else{
temp = first;
while(temp->next != NULL){
temp = temp->next;
}
current->next = NULL;
temp->next = current;
}
}
}
write(wPipe,&first,sizeof(Node) );
}
int main(){
//fork() the P processes
for(child = 0; child < P ; child++){
if((pid[child] = fork()) < 0){
perror("fork");
exit(1);
}
else if(pid[child] == 0){
close(fd[0]);
printf("Child #%d\n",getpid());
//call getPositions(...) method
getPosition(elementsList,child,P,SIZE,valueToFind,fd[1]);
close(fd[1]);
exit(0);
}
}
//read form the pipe and print the positions
Node *temp = NULL;
for(child = 0; child < P; child++){
temp = (Node*) malloc(sizeof(Node));
nbytes = read(fd[0],&temp, sizeof(Node));
while(temp != NULL){
printf("Position: %d\n",temp->val);
temp = temp->next;
}
}
}
struct节点;
类型定义结构节点{
int-val;
结构节点*下一步;
}节点;
静态整数元素列表[]={1,2,3,4,5,6,7,8,3,10,11,12,3,14,15,16,17,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,
1,2,3,4,5,6,7,8,9,3,11,12,13,14,3,16,17,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,
1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,3 };
//由进程调用以检查子向量中的值的方法
void getPosition(int elemList[],int start,int step,int size,int value,int wPipe){
Node*first=NULL;
节点*电流;
节点*温度;
int i;
对于(i=开始;i<大小;i+=步长){
if(值==elemList[i]){
当前=(节点*)malloc(sizeof(节点));
当前->val=i;
if(first==NULL){
第一个=电流;
first->next=NULL;
}否则{
温度=第一;
while(临时->下一步!=NULL){
温度=温度->下一步;
}
当前->下一步=空;
温度->下一步=当前;
}
}
}
写入(wPipe,&first,sizeof(Node));
}
int main(){
//fork()表示P进程
for(child=0;child值);
温度=温度->下一步;
}
}
}
一旦这些进程独立工作,它们就可以将同一地址用于不同的目的。基本上,不要在进程之间传递地址,除非数据位于映射到两个进程中相同地址的共享内存中。您需要将整数索引(仅)写入管道,并从管道中读取它们
这大大简化了您需要的代码:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
static int elementsList[] =
{
1, 2, 3, 4, 5, 6, 7, 8, 3, 10, 11, 12, 3, 14, 15, 16, 17,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
1, 2, 3, 4, 5, 6, 7, 8, 9, 3, 11, 12, 13, 14, 3, 16, 17,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 3
};
enum { SIZE = sizeof(elementsList)/sizeof(elementsList[0]) };
// method called by a process to check for the value in a subvector
static void getPosition(int elemList[], int start, int step, int size, int value, int wPipe)
{
for (int i = start; i < size; i += step)
{
if (value == elemList[i])
write(wPipe, &i, sizeof(i));
}
}
int main(void)
{
enum { P = 5 };
pid_t pid[P];
int fd[2];
int valueToFind = 3;
pipe(fd);
for (int child = 0; child < P; child++)
{
if ((pid[child] = fork()) < 0)
{
perror("fork");
exit(1);
}
else if (pid[child] == 0)
{
close(fd[0]);
printf("Child #%d\n", getpid());
getPosition(elementsList, child, P, SIZE, valueToFind, fd[1]);
close(fd[1]);
exit(0);
}
}
// read from the pipe and print the positions
close(fd[1]);
int index;
int n = 0;
printf("Seeking: %d\n", valueToFind);
while (read(fd[0], &index, sizeof(index)) == sizeof(index))
printf("%2d: Position: %2d (%d)\n", ++n, index, elementsList[index]);
return 0;
}
无法将指针发送到另一个进程。进程有单独的虚拟内存映射,一个进程中有效的地址在另一个进程中无效。我正在使用fork(),因此父进程的整个虚拟地址空间都应该复制到子进程中。或者我弄错了?一旦进程独立工作,它们可能会出于不同的目的使用相同的地址。基本上,不要在进程之间传递地址,除非数据位于映射到两个进程中相同地址的共享内存中。您需要将整数索引(仅)写入管道,并从管道中读取它们。您的代码缩进有些不尽如人意。通过查看代码很难判断这里是一个函数还是多个函数。如果您发布一个SSCCE()。
static int-elementsList[]={};//一些值
-什么值?很抱歉我的代码缩进。我试着把它修好。我试着只写和只读索引,但我遇到了同样的问题,因为一个进程可以在管道上写多次(他的子向量中有多个索引),我不知道如何通知读进程它从一个进程获得更多数据。这就是为什么我考虑像链表一样发送索引。
Child #55829
Child #55830
Child #55831
Child #55832
Child #55833
Seeking: 3
1: Position: 70 (3)
2: Position: 36 (3)
3: Position: 2 (3)
4: Position: 12 (3)
5: Position: 8 (3)
6: Position: 43 (3)
7: Position: 48 (3)
8: Position: 53 (3)
9: Position: 19 (3)
10: Position: 84 (3)