C 双指针(矩阵)的基本问题



我对编程比较陌生,我正在尝试编写一些代码来处理方形矩阵。不幸的是,我被困在开发的早期,因为代码

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,要么甚至不动态分配结构本身,因为没有必要这样做。这两个我都留给你考虑。

祝你好运。

相关内容

  • 没有找到相关文章

最新更新