可以在命名管道中发送和接收结构吗?

时间:2016-11-09 14:11:52

标签: c linux ubuntu process named-pipes

我有操作系统主题的练习。

问题是:创建两个进程P0和P1。 P0从输入文件中读取一个平方矩阵,然后发送到管道。 P1从管道读取矩阵,将其反转并写入输出文件。如果输入的矩阵不能反转,P1将消息写入输出文件并返回

我的代码如下。我用

编译
gcc -Wall main.c -o main.out

程序保持"分段错误(核心转储)"

请帮我找到失败的地方。抱歉我的英文不好

#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <sys/errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <fcntl.h>

#define FIFO1 "/tmp/ff.1"
#define FIFO2 "/tmp/ff.2"
#define PM 0666
#define PIPE_BUF 10240
#define SIGN(x) ((x%2)? -1:1)

extern int errno;

/*
matrix struct insist of 
size and a two-dimension array
*/
typedef struct {
    int size;
    float** array;
} matrix_t;

/*
prototypes
of some functions
*/
matrix_t readMatrix(char* filename);
void writeMatrix(char* filename, matrix_t matrix);
matrix_t invertMatrix(matrix_t matrix);
float detOfMatrix(float** arr, int size);
float** allocArr(int szRow, int szCol);
void FreeMem(float ** buff, int n);
/*
main here
return -1 if fork() == -1
return -3 if there is no pipe created
*/
int main(void) {
    //FILE *in, *out;

    //int fd[2];
    char input[] = "/home/thao/ass1/input.txt";
    char output[] = "/home/thao/ass1/output.txt";
    matrix_t sendmatrix, receivematrix, invertedmatrix;
    int childpid, readfd, writefd;
    if ((mknod(FIFO1, S_IFIFO | PM, 0) < 0) && (errno!=EEXIST)) {
        printf("Ko tao duoc fifo1 \n");
        return -1; 
    }
    if ((mknod(FIFO2, S_IFIFO | PM, 0) < 0) && (errno!=EEXIST)) {
        unlink(FIFO1);
        printf("Ko tao duoc fifo2 \n");
        return -1;
    }

    switch(childpid = fork()) {
        case -1: 
            printf("Ko tao duoc process\n");
            return -2;
        case 0: //Child
            if((readfd = open(FIFO1, 0)) < 0)
                perror("Child, ko mo duoc readfido\n");
            read(readfd, &receivematrix, PIPE_BUF);
            int det;
            if ((det = detOfMatrix(receivematrix.array, receivematrix.size)) == 0.0) {
                FILE *out = fopen(output, "w");
                fprintf(out, "Ma tran khong nghich dao duoc\n");
                return -1;
            }
            else {
                invertedmatrix = invertMatrix(receivematrix);   
                writeMatrix(output, invertedmatrix);
            }
            close(readfd);
        default: //Parent
            if ((writefd = open(FIFO1, 1)) < 0)
                perror("Parent, ko mo duoc writefifo\n");
            sendmatrix = readMatrix(input);
            write(writefd, &sendmatrix, PIPE_BUF);
            while(wait((int*)0) != childpid);
            close(writefd);
            if (unlink(FIFO1) < 0)
                perror("Khong the xoa ten FIFO1 tu file system\n");
            if (unlink(FIFO2) < 0) 
                perror ("Ko the xoa ten FIFO2 tu file system\n");
    }
    return 0;
}

/*
Function: invert matrix
Parameters: struct of matrix
Return: inverted matrix - type struct of matrix
*/
matrix_t invertMatrix (matrix_t matrix) {
    matrix_t result;
    result.size = matrix.size;
    result.array = matrix.array;
    float det = detOfMatrix(matrix.array, matrix.size);
    int i, j;
    for (i = 0; i < matrix.size; i++) 
        for (j = 0; j < matrix.size; j++) 
            result.array[i][j] = (1/det) * matrix.array[i][j];
    return result;
}

/*
Function: read matrix from input
Parameters: path of input file
Return: struct of matrix
*/
matrix_t readMatrix(char* filename) {
    FILE *in = fopen(filename, "r");
    char buf[10000];
    matrix_t matrix;
    int size = 0;
    matrix.array = 0;
    int i = 0, j = 0;
    while(fgets(buf, sizeof(buf), in)) {
        size += 1;
        for (j = 0; j < size; j++) {
            fscanf(in,"%f", &matrix.array[i][j]);
            printf("%f\t",matrix.array[i][j]);
        }
        printf("\n");
        i++;
    }
    matrix.size = size;
    return matrix;
}

/*
Function: write matrix to output
Parameters: path of output file, struct of matrix
Return: void
*/
void writeMatrix(char* filename, matrix_t matrix) {
    FILE *out = fopen(filename, "wb");
    int i = 0, j = 0;
    for (i = 0; i < matrix.size; i++) {
        for (j = 0; j < matrix.size; j++) {
            fprintf(out,"%f\t", matrix.array[i][j]);
            printf("%f\t",matrix.array[i][j]);
        }
        fprintf(out,"\n");
        printf("\n");
    }
    fclose(out);
}

/*
Function: calculate determinant of matrix
Parameters: struct of matrix
Return: determinant of matrix - type float 
*/
float detOfMatrix(float** arr, int size) {
    float result = 0;
    int m, n, i, j, k;

    float** subArr;
    if (size < 2) 
        return -1;
    if (size == 2)
        return arr[0][0] * arr[1][1] - arr[1][0] * arr[0][1];
    else {
        if (!(subArr = allocArr(size - 1, size - 1))) 
            return -1;
        for (i = 0; i < size; i++) {
            m = n = 0;
            for (j = 1; j < size; j++) {
                for (k = 0; k < size; k++) {
                    if (k != i) {
                        subArr[m][n] = arr[j][k];
                        n++;
                        if (n == size - 1) {
                            m++;
                            n = 0;
                        }
                    }
                }
            }
        result += SIGN(i) * arr[0][i]*detOfMatrix(subArr, size - 1);
        }
        FreeMem(subArr, size - 1);
        return result;  
    }
}

/*
Function: Allocate memory for array
*/
float ** allocArr(int szRow, int szCol) {
    int i;
    float **pArr;
    pArr = (float**)malloc(szRow * sizeof(float *));
    if (!pArr)
        return NULL;
    for (i = 0; i < szRow; i++) {
        pArr[i] = (float*)malloc(szCol * sizeof(float *));
        if (!pArr[i])
            return NULL;
    }
    return pArr;
}

/*
Function: free allocated memory
Parameters: pointer to memory
Return: void
*/
void FreeMem(float ** buff, int n) {
    int i;
    for (i = 0; i < n; i++) {
        if (buff[i])
        {
            free(buff[i]);
            buff[i] = NULL;
        }
    }
    if (buff)
        free(buff);
}

0 个答案:

没有答案