я пытаюсь запустить это на Linux, эта программа должна передавать массивы чисел с трубами дочерним элементам, и каждый дочерний элемент вычисляет gcd пар. Но я получаю "Ошибка сегментации (ядро сброшено)" ОШИБКА. Я проверил процесс ребенка, и сразу после read()
я попытался напечатать строку только для проверки, и она не работает. Странная вещь, что read
не возвращает -1, что означает, что он работал. Можно ли написать char **arr;
в трубу? или это большой для трубы, и именно поэтому он падает. Спасибо за любую помощь.
Кстати, ./v2_child1 в порядке, проблема возникает до execvp()
#include <stdarg.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE_LENGTH 100
#define FILE_NAME "numbers.txt"
char** readFromTextFile(char *fileName) {
FILE *f = fopen(fileName, "r");
if (f == NULL) {
printf("Error while opening file!");
return NULL;
}
char *line = (char*) malloc(MAX_LINE_LENGTH * sizeof(char));
char **pairs = (char**) malloc(50 * sizeof(char*));
int counter = 0;
while (!feof(f)) {
char *num1 = (char*) malloc(sizeof(char) * 2);
char *num2 = (char*) malloc(sizeof(char) * 2);
fgets(line, MAX_LINE_LENGTH, f);
sscanf(line, "%s %s", num1, num2);
pairs[counter] = num1;
pairs[counter + 1] = num2;
counter += 2;
}
pairs[counter] = NULL;
fclose(f);
return pairs;
}
int numOfPairs(char **arr) {
int count = 0;
while (arr[count] != NULL) {
count += 1;
}
if ((count % 2) != 0) {
printf("odd amount off numbers");
return -1;
} else {
return count / 2;
}
}
int main(int argc, char *argv[]) {
//read the pairs of numbers into array
char **numbers = readFromTextFile(FILE_NAME);
//returns the num of pairs to check
int num_pairs = numOfPairs(numbers);
//initialize the pipes
int write_pipe[2], read_pipe[2];
if (pipe(write_pipe) == -1 || pipe(read_pipe) == -1) {
fprintf(stderr, "Pipe operation failed!");
exit(0);
}
//child --> parent
int PARENT_READ = read_pipe[0]; // IN
int CHILD_WRITE = read_pipe[1]; // OUT
//parent --> child
int CHILD_READ = write_pipe[0];
int PARENT_WRITE = write_pipe[1];
pid_t status = fork(); // create child number 1
if (status < 0) { // error ocurred
fprintf(stderr, "Error with fork");
exit(0);
} else if (status > 0) { // parent go here
char **to_child1 = (char**) malloc(sizeof(char*) * (num_pairs / 2) * 2);
for (int i = 0; i < num_pairs / 2; ++i) {
to_child1[2 * i] = numbers[2 * i];
to_child1[2 * i + 1] = numbers[2 * i + 1];
}
if (close(CHILD_READ) == -1)
perror("problem while close CHILD_READ");
if (write(PARENT_WRITE, to_child1, sizeof(char*) * (num_pairs / 2) * 2)
== -1)
perror("problem while write to PARENT_WRITE");
if (close(PARENT_WRITE))
perror("problem while close PARENT_WRITE");
printf("wrote from parent to pipe\n\n");
} else { // child process
char **first_half = (char**) malloc(
sizeof(char*) * (num_pairs / 2) * 2);
printf("Hello form son 1\n");
if (close(PARENT_WRITE) == -1)
perror("Error while close");
read(CHILD_READ, first_half, sizeof(char*) * (num_pairs / 2) * 2);
printf("child got here"); // not printing this*
if (close(PARENT_READ) == -1) //read is unused
perror("Error while close");
if (dup2(CHILD_WRITE, STDOUT_FILENO) == -1) { //redirecting Stdout to pipe.
perror("dup2 error");
}
char *args[num_pairs / 2 + 1];
args[0] = "./v2_child1";
for (int i = 1; i < num_pairs / 2 + 1; ++i) {
args[i] = first_half[i];
}
execvp(args[0], args);
}
wait(NULL);
char **gcds = (char**) malloc(sizeof(char*) * (num_pairs / 2));
close(CHILD_WRITE);
read(PARENT_READ, gcds, sizeof(int));
for (int i = 0; i < num_pairs / 2; ++i) {
printf("The gcd of %d and %d is: %d - calculated from child 1\n",
atoi(numbers[i * 2]), atoi(numbers[i * 2 + 1]), atoi(gcds[i]));
}
/// another child to be created
}