쉬트라센 알고리즘 행렬곱셈 계산하는 코드 동적할당 읽기 액세스 오류.

조회수 816회
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<math.h>
void inMatrix(int[][1024], char *fname); 
void outMatrix(int[][1024], char *fname);
void Matrixadd(int[][1024], int[][1024], int[][1024]); 
void Matrixsub(int[][1024], int[][1024], int[][1024]);
void Matrixmul(int[][1024], int[][1024], int[][1024]); //단순한 알고리즘으로 구하는 행렬의 곱셈 함수
int threshold(int n); //임계값을 구하는 함수
void Strassen(int n, int[][1024], int[][1024], int[][1024]); //쉬트라센 알고리즘으로 구하는 행렬의 곱셈 함수

int result1[1024][1024];
int result2[1024][1024];
int matrix1[1024][1024];
int matrix2[1024][1024];
int a11[1024][1024], a12[1024][1024], a21[1024][1024], a22[1024][1024];
int b11[1024][1024], b12[1024][1024], b21[1024][1024], b22[1024][1024];
int c11[1024][1024], c12[1024][1024], c21[1024][1024], c22[1024][1024];
int m1[1024][1024], m2[1024][1024], m3[1024][1024], m4[1024][1024], m5[1024][1024], m6[1024][1024], m7[1024][1024];
int tmp1[1024][1024], tmp2[1024][1024];
int main() {

    int start, end;
    char fname1[50], fname2[50];

    printf("matrix1 행렬에 입력할 파일명을 입력하세요. : ");
    scanf("%s", &fname1);
    printf("matrix2 행렬에 입력할 파일명을 입력하세요. : ");
    scanf("%s", &fname2);

    inMatrix(matrix1, fname1);
    inMatrix(matrix2, fname2);

    start = clock();
    Matrixmul(matrix1, matrix2, result1);
    end = clock();
    printf("Navie 방식의 결과 시간 : %f ms\n", (double)(end - start));

    start = clock();
    Strassen(1024, matrix1, matrix2, result2);
    end = clock();
    printf("Strassen 방식의 결과 시간 : %f ms\n", (double)(end - start));

    outMatrix(result1,"Naive result.txt");
    outMatrix(result2, "Strassen result.txt");
    printf("결과가 Naive result.txt와 Strassen result.txt 파일에 저장되었습니다.\n");

}

void inMatrix(int matrix[][1024], char *fname) {
    FILE *fin;
    fin = fopen(fname, "rb"); //바이너리 파일로 파일은 연다
    char *arr = NULL;
    int idx = 0;
    if (fin == NULL) {
        printf("파일명이 없습니다.\n");
        return;
    }
    for (int i = 0; i < 1024; i++)
        for (int j = 0; j < 1024; j++) {
            matrix[i][j] = arr[idx];
            idx++;
        }
    fclose(fin);
    free(arr);
}
void outMatrix(int matrix[][1024], char *fname) {
    FILE *fout;
    fout = fopen(fname, "wt");
    for (int i = 0; i < 1024; i++) {
        for (int j = 0; j < 1024; j++)
            fprintf(fout, "%d ", matrix[i][j]);
        fprintf(fout, "\n");
    }
}
void Matrixadd(int matrix1[][1024], int matrix2[][1024], int result[][1024]) {
    for (int i = 0; i < 1024; i++)
        for (int j = 0; j < 1024; j++)
            result[i][j] = matrix1[i][j] + matrix2[i][j]; //행렬을 더함
}
void Matrixsub(int matrix1[][1024], int matrix2[][1024], int result[][1024]) {
    for (int i = 0; i < 1024; i++)
        for (int j = 0; j < 1024; j++)
            result[i][j] = matrix1[i][j] - matrix2[i][j]; //행렬을 뺌
}
void Matrixmul(int matrix1[][1024], int matrix2[][1024], int result[][1024]) {
    for(int i=0;i<1024;i++)
        for (int j = 0; j < 1024; j++) {
            result[i][j] = 0;
            for (int k = 0; k < 1024; k++)
                result[i][j] += matrix1[i][k] * matrix2[k][j]; //행렬을 곱함
        }
}
int threshold(int n) { 
    int threshold;
    double t = floor(log(n) / log(2) - 6);
    threshold = (int)floor(n / pow(2.0, t)) + 1;
    return threshold;
}
void Strassen(int n, int matrix1[][1024], int matrix2[][1024], int result[][1024]) {
    /*int a11[1024][1024], a12[1024][1024], a21[1024][1024], a22[1024][1024];
    int b11[1024][1024], b12[1024][1024], b21[1024][1024], b22[1024][1024];
    int c11[1024][1024], c12[1024][1024], c21[1024][1024], c22[1024][1024];
    int m1[1024][1024], m2[1024][1024], m3[1024][1024], m4[1024][1024], m5[1024][1024], m6[1024][1024], m7[1024][1024];
    int tmp1[1024][1024], tmp2[1024][1024];*/
    if (n <= threshold(n)) //임계값을 넘지 않으면
        Matrixmul(matrix1, matrix2, result); //일반적인 행렬곱셈으로 계산
    else {
        for (int i = 0; i < n / 2; i++) { //행렬의 부분을 나눠줌
            for (int j = 0; j < n / 2; j++) {
                a11[i][j] = matrix1[i][j];
                a12[i][j] = matrix1[i][j + n / 2];
                a21[i][j] = matrix1[i + n / 2][j];
                a22[i][j] = matrix1[i + n / 2][j + n / 2];
                b11[i][j] = matrix1[i][j];
                b12[i][j] = matrix1[i][j + n / 2];
                b21[i][j] = matrix1[i + n / 2][j];
                b22[i][j] = matrix1[i + n / 2][j + n / 2];
            }
        }
        //m1=(a11+a22)*(b11+b22)
        Matrixadd(a11, a22, tmp1);
        Matrixadd(b11, b22, tmp2);
        Strassen(n / 2, tmp1, tmp2, m1);
        //m2=(a21+a22)*b11
        Matrixadd( a21, a22, tmp1);
        Strassen(n / 2, tmp1, b11, m2);
        //m3=a11*(b12+b22)
        Matrixadd(b12, b22, tmp2);
        Strassen(n / 2, a11, tmp2, m3);
        //m4=a22*(b21+b11)
        Matrixadd(b21, b11, tmp2);
        Strassen(n / 2, a22, tmp2, m4);
        //m5=(a11+a12)*b22
        Matrixadd(a11, a12, tmp1);
        Strassen(n / 2, tmp1, b22, m5);
        //m6=(a21-a11)*(b11+b12)
        Matrixsub(a21, a11, tmp1);
        Matrixadd(b11, b12, tmp2);
        Strassen(n / 2, tmp1, tmp2, m6);
        //m7=(a12-a22)*(b21+b22)
        Matrixsub(a12, a22, tmp1);
        Matrixadd(b21, b22, tmp2);
        Strassen(n / 2, tmp1, tmp2, m7);

        //c11=m1+m4-m5+m7
        Matrixadd(m1, m4, tmp1);
        Matrixadd(m5, m7, tmp2);
        Matrixsub(tmp1, tmp2, c11);
        //c12=m3+m5
        Matrixadd(m3, m5, c12);
        //c21=m2+m4
        Matrixadd(m2, m4, c21);
        //c22=m1+m3-m2+m6
        Matrixadd(m1, m3, tmp1);
        Matrixadd(m2, m6, tmp2);
        Matrixsub(tmp1, tmp2, c22);

        for (int i = 0; i < n / 2; i++) {
            for (int j = 0; j < n / 2; j++) {
                result[i][j] = c11[i][j];
                result[i][j + n / 2] = c12[i][j];
                result[i + n / 2][j] = c21[i][j];
                result[i + n / 2][j + n / 2] = c22[i][j];
            }
        }
    }
}

실행을 시키면 파일 이름을 입력받는 부분까지만 실행이 됩니다. 디버깅을 시키면

'예외가 throw됨: 읽기 액세스 위반입니다. arr이(가) 0x1110112였습니다.'

이렇게 뜹니다. 동적할당에 문제가 있는 것 같은데 어떻게 수정을 해야될지 모르겠어요. 도와주세요.

1 답변

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)