편집 기록

편집 기록
  • 프로필 nowp님의 편집
    날짜2020.05.26

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


    #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였습니다.'
    

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

  • 프로필 알 수 없는 사용자님의 편집
    날짜2020.05.26

    쉬트라센 알고리즘 행렬곱셈 계산하는 코드 오류


    #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였습니다.' 이렇게 뜹니다. 동적할당에 문제가 있는 것 같은데 어떻게 수정을 해야될지 모르겠어요,, 도와주세요ㅜㅜ