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

时间:2015-01-15 19:46:14

标签: 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);
    /*
    ...
    ...
    ...
    */
    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()关闭后基本上所有矩阵信息都会丢失。为什么?我该如何解决?

提前致谢。

2 个答案:

答案 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; 
}