행렬에 관련된 소스 작성시 생기는 메모리 관련 문제 입니다..
글쓴이: fopenfclose / 작성시간: 수, 2015/12/16 - 10:56오후
단순히 행렬을 곱셈하는 건데요.
2차원 행렬을 2차원 배열이 아닌 1차원 포인터로 해서 나타냈습니다.
(요구 사항으로 인해서 입니다)
typedef struct Matrix { int numRows; int numCols; float * mat; } Matrix; // 이러한 구조체가 선언되어 있습니다. 메인 함수에서 Matrix * A = rand(3, 3); show(A); Matrix * B = rand(3, 3); show(B); Matrix * R = add(A, B); show(R); R = multiply(A, B); show(R); R = multiply(A, 3); show(R); R = transpose(A); show(R); ... 이렇게 선언하고 cpp 파일에서 // 행렬 전치 함수 예시 /* 1 2 3 1 4 7 4 5 6 -> 2 5 8 7 8 9 3 6 9 */ Matrix * transpose(const Matrix* A) { cout << "transpose" << endl; Matrix * matrix = new Matrix; matrix->numRows = A->numRows; matrix->numCols = A->numCols; matrix->mat = new float[A->numRows * A->numCols]; float ** afArr = make2Dmatrix(A, A->numRows, A->numCols); <- 2차원 배열로 float ** tAfArr = make2Dmatrix(A, A->numRows, A->numCols); <- 2차원 배열로 // 전치 행렬 for (int i = 0; i < A->numRows; i++) { for (int j = 0; j < A->numCols; j++) { tAfArr[i][j] = afArr[j][i]; cout << "sum" << tAfArr[i][j] << endl; <- 너무 큰 숫자들이 출력 } } // 1차원 배열로 변환 make1Dmatrix(matrix, tAfArr); // 메모리 해제 for (int i = 0; i < A->numRows; i++) { free(afArr[i]); free(tAfArr[i]); } free(afArr); free(tAfArr); return matrix; } /* *----------------------- * Matrix Multiplication *----------------------- */ Matrix* multiply(const Matrix* A, const Matrix* B) { if (A->numCols != B->numRows) { cout << "can not multiply" << endl; return NULL; } cout << "A * B multiple" << endl; Matrix * matrix = new Matrix; matrix->numRows = A->numRows; matrix->numCols = B->numCols; matrix->mat = new float[A->numRows * B->numCols]; float ** aArr = make2Dmatrix(A, A->numRows, A->numCols); float ** bArr = make2Dmatrix(B, B->numRows, B->numCols); float ** rArr = (float **)malloc(sizeof(float) * A->numRows); for (int i = 0; i < A->numRows; i++) { rArr[i] = (float *)malloc(sizeof(float) * B->numCols); } int sum = 0; for (int i = 0; i < A->numRows; i++) { for (int j = 0; j < B->numCols; j++) { sum = 0; for (int k = 0; k < A->numCols; k++) { sum += aArr[i][k] * bArr[k][j]; } rArr[i][j] = sum; cout << " sum " << rArr[i][j] << endl; } } // make1Dmatrix(matrix, rArr); for (int i = 0; i < A->numRows; i++) { free(aArr[i]); free(rArr[i]); } free(aArr); free(rArr); for (int i = 0; i < B->numRows; i++) free(bArr[i]); free(bArr); return matrix; } ... float ** make2Dmatrix(const Matrix * A, int a_numRows, int a_numCols) { // MAKE 2D float ** afArr = (float **)malloc(sizeof(float) * a_numRows); if (afArr == NULL) { cout << "mem alloc fail(transpose)" << endl; return NULL; } for (int i = 0; i < a_numRows; i++) { afArr[i] = (float *)malloc(sizeof(float) * a_numCols); if (afArr[i] == NULL) { cout << "transpose mem alloc fail" << endl; return NULL; } } for (int i = 0; i < A->numRows; i++) { memcpy(afArr[i], A->mat + (i * sizeof(float) * A->numCols), sizeof(float) * A->numCols); } return afArr; } // void make1Dmatrix(const Matrix * matrix, float ** tAfArr) { // 매트릭스에 복사 for (int i = 0; i < matrix->numRows; i++) memcpy(matrix->mat + (i * matrix->numCols * sizeof(float)), tAfArr[i], sizeof(float) * matrix->numCols); }
결과 값들이 너무 큰 숫자들 혹은 0, 1.02e 이런식의 숫자들이 출력 됩니다..
로직에는 문제가 없는 것 같은데 제가 어떤 부분이 틀린건지 모르겠습니다..
Forums:
참고해보세요.
- 숫자가 긴건. printf()로 확인해보세요.
- 정수형 int 를 float 형과 연산하려면. (float)(int) 혹은 ((float)(int)) 혹은 int * 1.0f 등으로 소수점이 있어야 할겁니다.
http://en.cppreference.com/w/cpp/io/manip/fixed
----------------------------------------------------------------------------
젊음'은 모든것을 가능하게 만든다.
매일 1억명이 사용하는 프로그램을 함께 만들어보고 싶습니다.
정규 근로 시간을 지키는. 야근 없는 회사와 거래합니다.
각 분야별. 좋은 책'이나 사이트' 블로그' 링크 소개 받습니다. shintx@naver.com
음 그래서 float * mat을 int *
음 그래서 float * mat을 int * mat으로 바꿨습니다...
댓글 달기