如何将命令行参数发送到malloc数组,然后将这些参数从父进程发送到子进程

时间:2019-05-30 21:06:19

标签: c

这是用于学校作业,我知道这是一个简单的问题,但是对于我的一生,我无法弄清楚自己在做什么错。

在父进程中,我需要将cmdline参数转换为整数,然后将参数存储在malloc数组中。然后,我需要一次将每个整数发送给子进程。然后,子进程将对从父进程传递的所有整数求和。一旦求和完成,它将把和返回给父进程。然后,父进程将打印出总和。

关于此代码,我不了解三件事。

  1. 接受命令行参数,将其转换为整数,并使用指向malloc数组的指针进行存储。我不明白为什么我不能只在父流程中写这个:
  int* numArray = (int*) malloc (argc * sizeof(int));
  for(int i = 0; i < argc; ++i){
     numArray[i] = atoi(argv[i+1]);
  }
  1. 如何将单个值发送到子进程进行求和?我可以一次读取它们,然后将和增加sumBuf中的值。然后sumBuf被下一个值覆盖,并再次将sum加sumBuf。我该怎么办?

  2. 如何在父进程中访问孩子的返回值?

将整数存储在malloc数组中会产生分段错误,而且我不知道如何纠正此错误。另外,由于fork返回孩子的PID,如果孩子返回一个和,那么该和不应该是孩子的PID?

  1. 对于malloc数组,我尝试在for循环内取消对numArray的引用,例如:
   *numArray[i] = atoi(argv[i+1]) 
  1. 我尝试过将单个值写入for循环内的管道

  2. 我知道fork返回子PID值,所以如果子返回sum,是否sum = p不能将sum存储到父PID值中?

    int main(int argc, char **argv){
      int *numArray = (int*) malloc (argc * sizeof(int));
      pid_t p;
      int fd[2];
      pipe(fd);
      p = fork()
      //error checks
    
      if(p == 0){//child process
           int sum = 0;
           int sumBuf = 0;
           close(fd[1]);//close write end
           for(int i = 0; i < argc; ++i){
               read(fd[0], sumBuf, sizeof(int));
               sum += sumBuf;
           }
           close(fd[0]);//close read end
           return sum;//return sum from child process
       }
       else{//parent process
           int sum = 0;
           close(fd[0]);//close read end
           for(int i = 0; i < argc; ++i){
               numArray[i] = atoi(argv[i+1]);
               write(fd[1], numArray[i], sizeof(int));
           }
           close(fd[1]);//close write end of pipe
           sum = p;
           printf("Sum = %d", sum);
           return 0;
       }
       free(numArray);
       return 0;
    }
    

当我尝试运行该程序时,出现分段错误消息。请不要称我为愚蠢的人,我理解该怎么做的想法,但是我不知道如何实现它。

2 个答案:

答案 0 :(得分:2)

在开始主要内容之前……我假设您已经将#include <stdlib.h>(以及<stdio.h><unistd.h>)放在这里。

此:

int *numArray = (int*) malloc (argc * sizeof(int));

可以用更好的替代方法代替:

int *numArray = malloc(argc * sizeof *numArray);

强制转换是不必要的。另外,根据需要使用sizeof *pointer更好 更改数组所指向的数据类型,则无需更改 sizeof。另外,如果您忘记了#include <stdlib.h>malloc()将返回int。进行类型转换基本上告诉编译器对此保持安静。如果您不投放演员表,则会收到一条诊断消息。

作为一个好习惯,最好检查一下 malloc(),例如

if (!numArray) {
    return EXIT_FAILURE;
}

此外,strtol()atoi()更好,因为前者提供了错误检查功能。

Nitpick:您需要将;放在fork()之后。

如果您需要将价值从孩子发回给父母,您将无能为力 您做到了:sum = p;。相反,如果 系统不支持双向管道(假设这样做更安全)。一世 将此作为练习留给您。

现在,write()read()的第二个参数需要一个指针。因此对于 例如,read()应该是:

read(fd[0], &sumBuf, sizeof sumBuf);

write()类似。

我无法理解您为什么不能只在{ 父进程。当然可以,而且像我这样的孩子更好 知道,应该无法访问分配的内存。

现在,最有可能造成段错误的原因是由 读取过去的数组边界。在这种情况下,malloc()。这可能更容易 用一个例子来解释:

如果您以这种方式运行它:

argv

./a.out 1 2 3 将为4,表示您只能访问argcargv[0]。现在, 这里有个提示:看看循环。

答案 1 :(得分:0)

  1. 我不明白为什么我不能只在父进程中编写这个代码-这正是您所做的并且应该可以正常工作。没有什么问题。

  2. readwrite函数将缓冲区的地址作为第二个参数。您试图传递变量的值。将以下行更改为-

read(fd[0], sumBuf, sizeof(int));

read(fd[0], &sumBuf, sizeof(int));

write(fd[1], numArray[i], sizeof(int));

write(fd[1], &(numArray[i]), sizeof(int));

这应该可以为您解决问题。另外,您的编译器必须已就这些警告您。请将所有警告视为错误。

  1. 您可以通过查看fork的返回值来访问父级中子级的进程ID。在您的情况下,变量p

您似乎在PID和过程返回的值之间也感到困惑。 PID是一个进程标识符。它是过程所独有的。返回值是该过程的主要功能返回的值。这可以是整数(两个进程也可以返回相同的值)。父级可以使用wait函数访问其子级返回的值。