我对编程一般都比较新,我正在尝试编写一些代码来处理方形矩阵。不幸的是,我在开发过程中很早就陷入了代码
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()关闭后基本上所有矩阵信息都会丢失。为什么?我该如何解决?
提前致谢。
答案 0 :(得分:1)
您只修改了函数中的本地自动变量m
。 C是一种按值传递的语言。如果你想通过地址传递,那么你必须传递一个地址,将形式参数声明为指向类型的指针,即使该类型已经是指针而你正在修改的是< em>指针本身 。
当您将某些内容作为输入/输出或输出参数传递时,如果您发现自己这样做:
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
}
因此,最直接的解决方法是将形式参数声明为指向指针的指针,从matr
main()
的地址
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
删除了不需要的强制转换,您可以阅读有关here的更多信息。
大约有六种方法可以做到这一点,但这是您已经拥有的代码最直接的方法。我建议将函数本身的分配作为ret-val返回,或者甚至不动态分配结构本身,因为没有必要这样做。我留给你考虑的两个。
祝你好运。
答案 1 :(得分:1)
在main函数中make 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;
}