这是用于学校作业,我知道这是一个简单的问题,但是对于我的一生,我无法弄清楚自己在做什么错。
在父进程中,我需要将cmdline参数转换为整数,然后将参数存储在malloc数组中。然后,我需要一次将每个整数发送给子进程。然后,子进程将对从父进程传递的所有整数求和。一旦求和完成,它将把和返回给父进程。然后,父进程将打印出总和。
关于此代码,我不了解三件事。
malloc
数组的指针进行存储。我不明白为什么我不能只在父流程中写这个: int* numArray = (int*) malloc (argc * sizeof(int));
for(int i = 0; i < argc; ++i){
numArray[i] = atoi(argv[i+1]);
}
如何将单个值发送到子进程进行求和?我可以一次读取它们,然后将和增加sumBuf
中的值。然后sumBuf
被下一个值覆盖,并再次将sum加sumBuf
。我该怎么办?
如何在父进程中访问孩子的返回值?
将整数存储在malloc
数组中会产生分段错误,而且我不知道如何纠正此错误。另外,由于fork返回孩子的PID,如果孩子返回一个和,那么该和不应该是孩子的PID?
malloc
数组,我尝试在for循环内取消对numArray
的引用,例如: *numArray[i] = atoi(argv[i+1])
我尝试过将单个值写入for循环内的管道
我知道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;
}
当我尝试运行该程序时,出现分段错误消息。请不要称我为愚蠢的人,我理解该怎么做的想法,但是我不知道如何实现它。
答案 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,表示您只能访问argc
至argv[0]
。现在,
这里有个提示:看看循环。
答案 1 :(得分:0)
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));
这应该可以为您解决问题。另外,您的编译器必须已就这些警告您。请将所有警告视为错误。
fork
的返回值来访问父级中子级的进程ID。在您的情况下,变量p
。 您似乎在PID和过程返回的值之间也感到困惑。 PID是一个进程标识符。它是过程所独有的。返回值是该过程的主要功能返回的值。这可以是整数(两个进程也可以返回相同的值)。父级可以使用wait
函数访问其子级返回的值。