删除嵌套函数调用中生成的中间指针的最佳做法是什么?
What is the best practice to delete intermediate pointers generated in nested function calls?
我正在用c写一个基本的矩阵库,矩阵数据结构是这样的:
typedef struct Matrix{
int rows;
int cols;
double complex *matrix;
} Matrix;
以及相应的初始化矩阵的函数和释放指针的函数(类似于c++中的构造函数和析构函数)
Matrix* InitializeMatrix(int r, int c){
Matrix* mat = malloc(sizeof(Matrix));
mat->rows = r;
mat->cols = c;
mat->matrix = (double complex *)malloc(r * c * sizeof(double complex));
return mat;
}
int DeleteMatrix(Matrix *mat){
mat->rows = 0;
mat->cols = 0;
free(mat->matrix);
mat->matrix = 0;
return 0;
}
这里是主要问题。假设我有两个函数
Matrix* fun1(Matrix* input){
//some operations
Matrix* mat = InitializeMatrix(r, c);
//some operations
return mat;
}
Matrix* fun2(Matrix* input){
//some operations
Matrix* mat = InitializeMatrix(r, c);
//some operations
return mat;
}
现在我有另一个函数想要嵌套fun1
和fun2
Matrix* fun3(Matrix* input){
return fun2(fun1(input));
}
通常当我调用一个函数时,我将不得不调用DeleteMatrix
来释放内存,但是在fun2(fun1(input))
中,对fun1(input)
生成的矩阵的引用不会被保存, 并且不能被释放。我知道我可以创建一个中间变量来进行引用,但我想保留嵌套函数调用,因为它简洁直观。我的整体设计有问题吗?如何克服这个问题?
你可以这样做,但它会创建中间函数:
Matrix* use_and_free(Matrix* input, Matrix* (*fct)(Matrix *)) {
Matrix* ret = fct(input);
DeleteMatrix(input);
return ret;
}
Matrix* fun3(Matrix* input){
return use_and_free(fun1(input), &fun2);
}
未显示如何使用输入参数。决定谁拥有分配的矩阵。这样行吗? (假设所有权转移给 fun2)
Matrix* fun2(Matrix* input){
//some operations
Matrix* mat = InitializeMatrix(r, c);
//some operations
DeleteMatrix(input);
return mat;
}
一个选择是更改函数原型,以便 fun1()
和 fun2()
接受第二个参数,即指向 Matrix
的指针。然后你可以改变函数体,如果这个参数是 NULL
,那么分配一个新的 Matrix
,否则使用 output
Matrix
。例如:
Matrix* fun1(Matrix* input, Matrix* output){
//some operations
Matrix* mat;
if (output == NULL){
mat = InitializeMatrix(input->rows, input->cols);
} else {
mat = output;
}
//some operations
return mat;
}
这里我假设你原函数中未声明的r
和c
指的是input
Matrix
的行数和列数.如果你想让fun1()
分配一个新的Matrix
,可以这样调用:
Matrix* result = fun1(input, NULL);
如果你想使用预分配的 Matrix
:
Matrix* mtrx = InitializeMatrix(3, 3);
mtrx = fun1(input, mtrx);
如果您想将 fun1()
和 fun2()
链接在一起:
mtrx = fun2(fun1(input, mtrx), mtrx);
尽管让外部函数调用进行分配可能会更好;这样 mtrx
永远是一个中间结果,你只需要创建一个新的 Matrix
指针就可以得到一个新的结果。请注意,您仍然需要为 mtrx
:
分配 space
result = fun2(fun1(input, mtrx), NULL);
您可以将更多功能链接在一起,但这可能会越过门槛而变得不当:
result = fun3(fun2(fun1(input, mtrx), mtrx), NULL);
另外,请注意您的 DeleteMatrix()
功能有问题。无需将字段清零,您需要 free(mat)
以及 free(mat->matrix)
:
int DeleteMatrix(Matrix* mat){
free(mat->matrix);
free(mat);
return 0;
}
我正在用c写一个基本的矩阵库,矩阵数据结构是这样的:
typedef struct Matrix{
int rows;
int cols;
double complex *matrix;
} Matrix;
以及相应的初始化矩阵的函数和释放指针的函数(类似于c++中的构造函数和析构函数)
Matrix* InitializeMatrix(int r, int c){
Matrix* mat = malloc(sizeof(Matrix));
mat->rows = r;
mat->cols = c;
mat->matrix = (double complex *)malloc(r * c * sizeof(double complex));
return mat;
}
int DeleteMatrix(Matrix *mat){
mat->rows = 0;
mat->cols = 0;
free(mat->matrix);
mat->matrix = 0;
return 0;
}
这里是主要问题。假设我有两个函数
Matrix* fun1(Matrix* input){
//some operations
Matrix* mat = InitializeMatrix(r, c);
//some operations
return mat;
}
Matrix* fun2(Matrix* input){
//some operations
Matrix* mat = InitializeMatrix(r, c);
//some operations
return mat;
}
现在我有另一个函数想要嵌套fun1
和fun2
Matrix* fun3(Matrix* input){
return fun2(fun1(input));
}
通常当我调用一个函数时,我将不得不调用DeleteMatrix
来释放内存,但是在fun2(fun1(input))
中,对fun1(input)
生成的矩阵的引用不会被保存, 并且不能被释放。我知道我可以创建一个中间变量来进行引用,但我想保留嵌套函数调用,因为它简洁直观。我的整体设计有问题吗?如何克服这个问题?
你可以这样做,但它会创建中间函数:
Matrix* use_and_free(Matrix* input, Matrix* (*fct)(Matrix *)) {
Matrix* ret = fct(input);
DeleteMatrix(input);
return ret;
}
Matrix* fun3(Matrix* input){
return use_and_free(fun1(input), &fun2);
}
未显示如何使用输入参数。决定谁拥有分配的矩阵。这样行吗? (假设所有权转移给 fun2)
Matrix* fun2(Matrix* input){
//some operations
Matrix* mat = InitializeMatrix(r, c);
//some operations
DeleteMatrix(input);
return mat;
}
一个选择是更改函数原型,以便 fun1()
和 fun2()
接受第二个参数,即指向 Matrix
的指针。然后你可以改变函数体,如果这个参数是 NULL
,那么分配一个新的 Matrix
,否则使用 output
Matrix
。例如:
Matrix* fun1(Matrix* input, Matrix* output){
//some operations
Matrix* mat;
if (output == NULL){
mat = InitializeMatrix(input->rows, input->cols);
} else {
mat = output;
}
//some operations
return mat;
}
这里我假设你原函数中未声明的r
和c
指的是input
Matrix
的行数和列数.如果你想让fun1()
分配一个新的Matrix
,可以这样调用:
Matrix* result = fun1(input, NULL);
如果你想使用预分配的 Matrix
:
Matrix* mtrx = InitializeMatrix(3, 3);
mtrx = fun1(input, mtrx);
如果您想将 fun1()
和 fun2()
链接在一起:
mtrx = fun2(fun1(input, mtrx), mtrx);
尽管让外部函数调用进行分配可能会更好;这样 mtrx
永远是一个中间结果,你只需要创建一个新的 Matrix
指针就可以得到一个新的结果。请注意,您仍然需要为 mtrx
:
result = fun2(fun1(input, mtrx), NULL);
您可以将更多功能链接在一起,但这可能会越过门槛而变得不当:
result = fun3(fun2(fun1(input, mtrx), mtrx), NULL);
另外,请注意您的 DeleteMatrix()
功能有问题。无需将字段清零,您需要 free(mat)
以及 free(mat->matrix)
:
int DeleteMatrix(Matrix* mat){
free(mat->matrix);
free(mat);
return 0;
}