#c #matrix #memory-leaks #dynamic-memory-allocation #function-definition
#c #матрица #утечки памяти #динамическое выделение памяти #функция-определение
Вопрос:
Ниже приведена компилируемая программа, большая часть которой сделана Крейгом Эсти, который помог мне с другим вопросом. Я просто использую его, чтобы люди могли протестировать программу, но проблема, с которой я сталкиваюсь, связана с функцией суммирования двух матриц. Точно, функция
Matrix* sum(Matrix* mat1, Matrix* mat2){
int row, col, k, l;
Matrix *mat3;
mat3 = allocateMemory(mat1->row, mat1->col);
if((mat1->row == mat2->row)amp;amp;(mat1->col == mat2->col)){ //verify if the two matrices have the same order
for (row = 0; row < mat1->row; row ){
for (col = 0; col < mat1->col; col ){
k = row * mat1->col col;//create index for matrix 1 element
l = row * mat2->col col;//create index for matrix 2 element
mat3->a[k] = mat1->a[k] mat2->a[l]; //sum elements and store in mat3
}
}
return mat3;
}
}
Компилируемая программа на C
#include <stdio.h>
#include <stdlib.h>
typedef struct matrix {
int row;
int col;
int *a;
} Matrix;
Matrix *allocateMemory(int row, int col)
{
Matrix *mat = malloc(sizeof(*mat));
if (mat == NULL) {
perror("malloc");
exit(1);
}
mat->row = row;
mat->col = col;
mat->a = calloc(row * col, sizeof(*mat->a));
if (mat->a == NULL) {
perror("calloc");
exit(1);
}
return mat;
}
void printMatrix(Matrix *mat)
{
int row, col, off;
for (row = 0; row < mat->row; row ) {
for (col = 0; col < mat->col; col ) {
off = (row * mat->col) col;
printf("%d ", mat->a[off]);
}
printf("n");
}
}
void matrix_fill(Matrix *mat)
{
int row, col, off;
int val = 1;
for (row = 0; row < mat->row; row ) {
for (col = 0; col < mat->col; col ) {
off = (row * mat->col) col;
mat->a[off] = val ;
}
}
}
Matrix* sum(Matrix* mat1, Matrix* mat2){
int row, col, k, l;
Matrix *mat3;
mat3 = allocateMemory(mat1->row, mat1->col);
if((mat1->row == mat2->row)amp;amp;(mat1->col == mat2->col)){
for (row = 0; row < mat1->row; row ){
for (col = 0; col < mat1->col; col ){
k = row * mat1->col col;
l = row * mat2->col col;
mat3->a[k] = mat1->a[k] mat2->a[l];
}
}
return mat3;
}
}
int main(void){
Matrix *m1 = allocateMemory(3,3);
Matrix *m2 = allocateMemory(3,3);
Matrix *m3 = allocateMemory(3,3);
matrix_fill(m1);
matrix_fill(m2);
printf("nMatrix 1n");
printMatrix(m1);
printf("nMatrix 2n");
printMatrix(m2);
Matrix* sum(Matrix* m1, Matrix* m2);
printf("nSum of matrices m1 and m2n");
printMatrix(m3);
return 0;
}
Предполагается, что функция sum возвращает результат суммы двух заданных матриц, но она не работает, просто, кажется, возвращает нулевое значение. Но я не мог понять, почему это не работает.
Комментарии:
1. В сторону: чтобы избежать
int
переполнения огромными массивами. рассмотримcalloc(row * col, sizeof(*mat->a));
—>calloc((size_t)row * col, sizeof(*mat->a));
или тому подобное.
Ответ №1:
Функция имеет неопределенное поведение и утечку памяти, поскольку она ничего не может вернуть в случае, когда условие в операторе if
if((mat1->row == mat2->row)amp;amp;(mat1->col == mat2->col)){
будет оценено как false.
Функция может быть объявлена и определена следующим образом
Matrix * sum( const Matrix *mat1, const Matrix *mat2 )
{
Matrix *mat3 = NULL;
if ( ( mat1->row == mat2->row ) amp;amp; ( mat1->col == mat2->col ) )
{
mat3 = allocateMemory( mat1->row, mat1->col );
if ( mat3 != NULL )
{
for ( int row = 0; row < mat1->row; row )
{
for ( int col = 0; col < mat1->col; col )
{
int k = row * mat1->col col;
mat3->a[k] = mat1->a[k] mat2->a[k];
}
}
}
}
return mat3;
}
В рамках функции main это распределение
Matrix *m3 = allocateMemory(3,3);
является избыточным, а также приводит к утечке памяти, если вы вызовете функцию like (то есть, если вы вызовете функцию так, как это требуется).
m3 = sum( m1, m2 );
И эта запись в основном
Matrix* sum(Matrix* m1, Matrix* m2);
это объявление функции. Это не вызов функции.
Вы должны написать, как показано выше
Matrix *m3 = NULL;
//...
m3 = sum( m1, m2 );