分段错误 - 如何从管道写入和读取链接列表

时间:2013-11-17 18:50:52

标签: c linux list

我有一个整数数组,我必须确定哪些索引可以使用P进程找到给定值。我拆分向量,以便每个进程可以在子向量中搜索该值,并在管道上写入索引。一个进程可以在多个位置找到该值,并且我使用一个简单的链表来存储每个进程的索引。在那之后我写在管道上。我的问题是读数是偏的,我得到了分段错误,因为列表的大小比我声明的要大。我该怎么做呢?

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;
        }
  }
}

1 个答案:

答案 0 :(得分:3)

一旦进程独立工作,他们就可以使用相同的地址用于不同的目的。基本上,除非数据位于两个进程中映射到同一地址的共享内存中,否则不要在进程之间传递地址。您需要将整数索引(仅)写入管道,并从管道中读取它们。

这大大简化了您需要的代码:

#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;
}

请注意,父进程在进入循环之前关闭管道的写入端是至关重要的。

示例输出:

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)