在任务中,我使用各种基本矩阵方法,例如
-multiply -transpose -倒置 -triangularize
每个方法都使用matrx_memory_alloc(float **m,int row, int col)
为结果矩阵分配内存
现在我有一种方法,在伪代码中执行类似这样的操作
float **final_function(float matrix, int row, int col){
float **result= invert(multiply(matrix,transpose(matrix, int row, int col), int row, int col)
return result
}
我还有一个方法matrx_memory_dealloc(float **m, int row, int col)
,它以分配的类似方式释放内存。
现在:
如何正确释放与final_function
相关的每个方法中完成的每个内存分配?换句话说:我什么时候应该调用释放方法?
如果我在final_function
之后调用释放方法,据我所知,应该只释放最终函数中使用的最后一个分配,而不是之前所有相关方法的分配。我错了吗?
答案 0 :(得分:2)
假设你真的想要一些可编译的代码:
float **invert(float **matrix, int row, int col);
float **transpose(float **matrix, int row, int col);
float **multiply(float **matrix1, int row1, int col1, float **matrix2, int row2, col2);
float **final_function(float **matrix, int row, int col)
{
float **result = invert(multiply(matrix, row, col, transpose(matrix, row, col), row, col), row, col);
return result;
}
(主要区别是在调用3个函数的行中丢失int
),然后你就像写入一样隐藏到任何东西。无法释放由函数分配的内存。您必须更明确地编写代码:
float **invert(float **matrix, int row, int col);
float **transpose(float **matrix, int row, int col);
float **multiply(float **matrix1, int row1, int col1, float **matrix2, int row2, col2);
float **final_function(float **matrix, int row, int col)
{
float **t1 = transpose(matrix, row, col);
float **t2 = multiply(matrix, row, col, t1, col, row); // Dubious dimensions
float **result = invert(t2, row, col);
mtrix_memory_dealloc(t1, col, row);
mtrix_memory_dealloc(t2, row, col); // Dubious dimensions
return result;
}
这段代码更像是一个原则'比完全工作的代码。您需要知道输出矩阵的大小。我推断,当输入为(row x col)时,转置的输出矩阵有(col x row);我没有坐下来考虑multiply()
输出的大小(但它是(行x行)或(col x col),除非我完全偏离基础)。在这种情况下,对invert()
的调用是错误的 - 除非row == col
;它应该是invert(t2, row, row)
或invert(t2, col, col)
。同样可以修复对mtrix_memory_dealloc(t2, …)
的调用。
显然,您可以在致电t1
之前免费invert()
。
您没有向我们展示main()
或transposeMatrix()
功能,因此我们无法说明您的代码崩溃的原因。问题不在于您的内存分配或释放功能。在这里,我们通过实施transposeMatrix()
和matrix_print()
函数将其嵌入(未更改)到程序中:
#include <stdio.h>
#include <stdlib.h>
extern void matrix_print(const char *tag, int m, int n, float **matrix);
extern float **transposeMatrix(int m, int n, float **matrix);
extern float **matrx_memory_alloc(int m, int n);
extern void matrx_memory_dealloc(int m, float **array);
float **matrx_memory_alloc(int m, int n)
{
int i;
float **arr = malloc(m * sizeof(*arr));
for (i = 0; i < m; i++)
{
arr[i] = malloc(n * sizeof(**arr));
}
return arr;
}
void matrx_memory_dealloc(int m, float **array)
{
int i;
for (i = 0; i < m; i++)
{
free(array[i]);
}
free(array);
}
float **transposeMatrix(int m, int n, float **matrix)
{
float **result = matrx_memory_alloc(n, m);
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
result[j][i] = matrix[i][j];
}
return result;
}
int main(void)
{
float **matrix = matrx_memory_alloc(3, 4);
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
matrix[i][j] = (i + j + 1) + ((9 - i - j) / 10.0);
}
matrix_print("Initial", 3, 4, matrix);
float **transpose = transposeMatrix(3, 4, matrix);
matrix_print("Transpose", 4, 3, transpose);
matrx_memory_dealloc(4, transpose);
matrx_memory_dealloc(3, matrix);
return 0;
}
void matrix_print(const char *tag, int m, int n, float **matrix)
{
int i, j;
printf("%s (%d x %d):\n", tag, m, n);
for (i = 0; i < m; i++)
{
char *pad = "[";
for (j = 0; j < n; j++)
{
printf("%s%6.3f", pad, matrix[i][j]);
pad = ", ";
}
printf("%s", " ]\n");
}
}
它在严格的编译器选项下完全编译:
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition -Werror so24276121.c -o so24276121
我注意到valgrind
给了它一个干净的健康状况:
==34372== Memcheck, a memory error detector
==34372== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==34372== Using Valgrind-3.10.0.SVN and LibVEX; rerun with -h for copyright info
==34372== Command: ./so24276121
==34372==
Initial (3 x 4):
[ 1.900, 2.800, 3.700, 4.600 ]
[ 2.800, 3.700, 4.600, 5.500 ]
[ 3.700, 4.600, 5.500, 6.400 ]
Transpose (4 x 3):
[ 1.900, 2.800, 3.700 ]
[ 2.800, 3.700, 4.600 ]
[ 3.700, 4.600, 5.500 ]
[ 4.600, 5.500, 6.400 ]
==34372==
==34372== HEAP SUMMARY:
==34372== in use at exit: 0 bytes in 0 blocks
==34372== total heap usage: 9 allocs, 9 frees, 152 bytes allocated
==34372==
==34372== All heap blocks were freed -- no leaks are possible
==34372==
==34372== For counts of detected and suppressed errors, rerun with: -v
==34372== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
答案 1 :(得分:0)
我不太了解c矩阵,但是你分配的内存将有地址,所以如果你有指向这些地址的指针,你应该能够使用它们的名称解除分配它们。 虽然我希望如果你的函数返回矩阵内存类型,那么它们应该在返回时在每个函数的末尾被删除。我认为普通内存是通过EAX或EAX传递的:EBX组合,它被放置在寄存器中,然后弹回到你的变量或其他东西。但是更大的内存似乎被编码成一个隐藏的指针参数,指向&#34; RETURN&#34;值将由您的函数存储,然后从那里读取内存。 所以你可能更容易使用像这样的结构
matrix *M;
MatrixFunction( matrix* M, int rows, int columns);
或
MatrixFunction( matrix* M, matrix N, int rows, int columns)
然后编码如下:
invert(Multiply(M,.....))))
这样只有一个M可以创建内存而只有一个M来摧毁内存