C双指针(矩阵)的基本问题
一般来说,我对编程比较陌生,我正在尝试编写一些代码来处理平方矩阵。不幸的是,我在开发的早期就被卡住了,因为代码C双指针(矩阵)的基本问题,c,pointers,malloc,double-pointer,C,Pointers,Malloc,Double Pointer,一般来说,我对编程比较陌生,我正在尝试编写一些代码来处理平方矩阵。不幸的是,我在开发的早期就被卡住了,因为代码 typedef struct Matrix_t{ float** content; size_t size; } Matrix_t; int main(int argc, char** argv) { Matrix_t* matr; initMatrix(matr,s); /* ... ... ... */
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;
}
typedef结构矩阵{
浮动**内容;
大小;
}矩阵t;
int main(int argc,字符**argv){
矩阵矩阵;
初始矩阵(matr,s);
/*
...
...
...
*/
返回0;
}
void initMatrix(Matrix_t*m,size_t s){
int i;
m=(矩阵t*)malloc(矩阵t的大小);
m->content=(float**)malloc(s*sizeof(float*);
对于(i=0;icontent[i]=(float*)malloc(s*sizeof(float));
}
m->size=s;
}
在initMatrix()完成后,将立即执行SIGSEGV。
使用调试器,我发现在initMatrix()关闭后,基本上所有矩阵信息都丢失了。为什么会丢失?我如何修复它
提前感谢。您只修改了函数中的一个局部自动变量
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(矩阵**pp,大小)
{
int i;
矩阵_t*m=malloc(sizeof(矩阵_t));
m->content=malloc(s*sizeof(float*);
对于(i=0;icontent[i]=malloc(s*sizeof(float));
m->size=s;
*pp=m;//注意:保存指向输出目标的指针
}
int main(int argc,字符**argv)
{
矩阵_t*matr=NULL;
initMatrix(&matr,s);//注意:指针的传递地址
/*
...
...
...
*/
返回0;
}
我省略了错误检查(或者我应该说,我没有添加任何错误检查,因为一开始就没有错误检查),并从malloc
中删除了不必要的强制转换,您可以阅读更多内容
有大约六种方法可以做到这一点,但这是最直接的代码。我建议要么将函数本身的分配返回为ret val,要么甚至不动态分配结构本身,因为不需要这样做。这两种方法我都留给您思考
祝你好运。在主函数中设置matr=NULL,因此,请尝试:
main(){
Matrix_t *matr=NULL;
/*Declare and initialize "s" variable.... */
initMatrix(&matr,s); /* See below... */
/*
.....
*/
}
在函数initMatrix中的矩阵_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=…
如果您认为这会影响从main()传入的指针
,您可能想重新考虑一下。此外,我认为没有理由首先动态分配矩阵。\u t
。它的相关内容已经是动态管理的。除了堆上的几个字节之外,您还能获得什么?Variablem
是函数initMatrix
中的一个局部变量。您设置它的任何内容都是无关的本质上,分配的内存“丢失”(也称内存泄漏)一旦这个函数完成。@barakmanosm
是本地的,但实际上它是matr
变量的地址。你把一个矩阵指针传递给这个函数,函数指针指向分配的内存,在返回initMatrix
之后,m
应该仍然有分配的内存地址。我错了吗?奇怪的是e不起作用。你认为呢?啊!应该传递指针的地址。我得到了它,多亏了WhozCraigI建议避免使用短语“双指针”。它可以指指向指针的指针,就像这里一样,但它也指类型double*
。单击“双指针”标记,它将带您进入讨论此问题的标记wiki。
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;
}