2011-01-27 55 views
0

我试图写组成的字符数组,一个整数值,并且一个指向管的结构写入结构的管。该结构表示单链表中的节点。阅读和用C

//Define a linked-list node object 
typedef struct node{ 
    char word[128]; 
    int frequency; 
    struct node *next; 
} NODE; 

该程序的目标是使用管道将节点从几个并发的子进程传递给父进程。我已经实现的管道结构似乎可以正常使用字符数组,但如果我尝试传递整个节点对象,则不起作用。

//for each file argument, create a child process 
     for (i = 1; i < argc; i ++) 
     { 
      pipe(p[i-1]); 
      pid = fork(); 

      if (pid == 0) 
      { 
       //child process 
       close(p[i-1][0]); 
       NODE *tmp; 
       NODE *out = freqCheck(argv[i], tmp); 
       write(p[i-1][1], out, sizeof(NODE)); 
       exit(0); 
      } 
     } 
if (pid > 0){ 
       //parent process 
       int j; 
       for (j = 0; j < argc-1; j++) 
       { 
        close(p[j][1]); 
        NODE *tmp; 
        read(p[j][0], tmp, sizeof(NODE)); 

        printf("%s\n", tmp->word); 
       } 


      } 

当父进程试图从管道读取和解释结构的属性之一,我只是得到空值回来。

我使用2个元件整数数组的数组跟踪每个子进程管。上面的printf语句返回null返回时间。

任何想法我做错了什么?

代码为FrqCheck方法:

//Method for determining the most occuring word 
NODE * freqCheck(char *file, NODE *max) 
{ 
    int i; 
    FILE *f; 
    char str[128]; 

    //Set up head and tail nodes 
    NODE *head = NULL; 
    NODE *tail = NULL; 

    if ((f = fopen(file, "r")) == NULL) 
     { 
      //sprintf(output, "%s could not be opened.", file); 
     }else 
     { 
      //scan each word of the input file 
      while(fscanf(f, "%s ", str) != EOF) 
      { 
       //if the linked-list has no nodes, create one 
       if (head == NULL) 
       { 
        NODE *n; 
        n = (NODE *)malloc(sizeof(NODE)); 
        strcpy(n->word, str); 
        n->frequency = 1; 
        n->next = NULL; 
        head = n; 
        tail = n; 

       }else{ //search the linked list for the found word. 

        NODE *current = head; 
        int found = 0; 

        while((current != NULL) && (found == 0)) 
        { 
         //if the word is found increment the frequency 
         if (strcmp(current->word, str) == 0) 
         { 
          current->frequency ++; 
          found = 1; 
         }else 
         { 
          current = current->next; 
         } 
        } 

        //if the word is not found, create a node and add to the liked-list 
        if (found == 0) 
        { 
         NODE *new; 
         new = (NODE *)malloc(sizeof(NODE)); 
         strcpy(new->word, str); 
         new->frequency = 1; 
         new->next = NULL; 
         tail->next = new; 
         tail = new; 
        } 
       } 
      } 
      //traverse the linked-list and find the word with the maximum frequency 
      NODE *tmp = head; 
      max = tmp; 

      while (tmp != NULL) 
      { 
       if (tmp->frequency > max->frequency) 
       { 
        max = tmp; 
       }else 
       { 
        tmp = tmp->next; 
       } 
      } 
      //sprintf(output, "%s %s %d", file, max->word, max->frequency); 
     } 
    //printf("%s\n", max->word); 
    return max; 
} 

回答

1

你在哪里你NODE结构分配存储空间? freqCheck是否分配存储空间?在父进程,当你调用read()然后printf,你在一个未初始化的NODE指针传递,所以当然你要未定义行为。

+0

是频率检查构造链表并为每个节点分配内存。该方法扫描文件中的单词,并确定哪个单词出现最多。它返回一个节点实例。 – isometrik 2011-01-27 23:35:29

+0

但是... show source ... – Svisstack 2011-01-27 23:36:06

0

使用缓冲读谁,直到整个结构中读取的数据将被readed,因为从parrent代码可以从孩子那你读谁不存在数据的代码之前执行。

0

你需要考虑两件事情:
1)执行方面的协调:

这是什么之类的东西锁,信号量,事件等都是。他们强制执行命令(您的代码行)的顺序。正是出于这个原因,这些在进程间运行的版本,就像那些为线程运行的版本一样。你想)在SEM上的一个信号这里 - 作家过程应该张贴()的SEM当一个节点已全部发送,阅读过程中应等待(试图读取下一个之前。

2)内存:
进程不共享地址空间。因此,读者和写作者的过程都有不同的内存块。一个管道工作正常,但它就像一个套接字 - 你将所有的对象序列化和反序列化成原始字节流。考虑到你的结构有多小,你可以考虑的另一件事是共享内存。

要考虑的最后一件事:您的节点结构中“下一个”节点的指针需要在子进程中更新。同样,它将把这些节点复制到它自己的地址空间中的位置,所以'下一个'指针必须相应地更新。