我对编程比较陌生,我正在尝试编写一些代码来处理方形矩阵。不幸的是,我被困在开发的早期,因为代码
typedef struct Matrix_t{
float** content;
size_t size;
} Matrix_t;
int main(int argc, char** argv) {
Matrix_t* matr;
initMatrix(matr,s);
/*
...
...
...
*/
return 0;
}
void initMatrix(Matrix_t* m, size_t s) {
int i;
m = (Matrix_t*) malloc(sizeof(Matrix_t));
m->content = (float**) malloc(s*sizeof(float*));
for(i=0;i<s;i++){
m->content[i] = (float*) malloc(s*sizeof(float));
}
m->size = s;
}
将在 initMatrix() 完成后立即进行 SIGSEGV。使用调试器,我发现基本上所有矩阵信息在 initMatrix() 关闭后都会丢失。这是为什么呢?我该如何解决它?
提前谢谢。
在主函数中制作 matr=NULL,因此,请尝试:
main(){
Matrix_t *matr=NULL;
/*Declare and initialize "s" variable.... */
initMatrix(&matr,s); /* See below... */
/*
.....
*/
}
在函数 initMatrix 中使用指向 Matrix_t *m 中的指针
void initMatrix(Matrix_t **m, size_t s)
{
Matrix_t *aux=(Matrix_t*)malloc(sizeof(Matrix_t));
/*check if matrix already allocated */
if(*m != NULL)
{
/*Make a free matrix function to free the matrix before use*/
free_my_matrix(m);
*m=NULL;
}
/***
Work with aux....
aux->content=...malloc....
***/
/* make your base pointer be aux */
*m=aux;
}
您只修改函数中m
的局部自动变量。C 是一种按值传递语言。如果要按地址传递,则必须传递地址,将形式参数声明为指向类型的指针,即使该类型已经是指针并且您正在修改的是指针本身。
当您将某些内容作为 in/out 或 out 参数传递时,如果您发现自己这样做:
void foo(Type *p)
{
p = malloc(...)
}
您没有修改p
指向的数据,而是修改p
本身,并且调用方将不知道更改。入口时存储在p
中的地址将丢失。其中:
void foo(Type *p)
{
*p = ....
}
正在修改p
指向的内容。也就是说,如果Type
已经是指针类型,并且您想要修改指针本身,则必须执行以下操作:
void foo(Type **pp) // declare a pointer-to-pointer-to-type
{
*pp = malloc(....) // dereference to store the address returned from malloc
// in the pointer pointed to by pp
}
因此,最直接的解决方法是将形式参数声明为指针到指针类型,从main()
传递matr
的地址
void initMatrix(Matrix_t **pp, size_t s)
{
int i;
Matrix_t *m = malloc(sizeof(Matrix_t));
m->content = malloc(s*sizeof(float*));
for(i=0;i<s;i++)
m->content[i] = malloc(s*sizeof(float));
m->size = s;
*pp = m; // note: saving pointer to the output target
}
int main(int argc, char** argv)
{
Matrix_t* matr = NULL;
initMatrix(&matr,s); // note: passing address of pointer
/*
...
...
...
*/
return 0;
}
我省略了错误检查(或者我应该说,我没有添加任何错误,因为一开始就没有添加任何错误)并从malloc
中删除了不需要的强制转换,您可以在此处阅读更多信息。
大约有六种方法可以做到这一点,但这是最直接的,你已经拥有的代码。我建议要么从函数本身返回分配作为 ret-val,要么甚至不动态分配结构本身,因为没有必要这样做。这两个我都留给你考虑。
祝你好运。