【问题标题】:C: How to pass a double pointer to a functionC:如何将双指针传递给函数
【发布时间】:2011-05-19 08:38:53
【问题描述】:

当我将双指针传递给函数以初始化内存时,我遇到了分段错误

int main()
{
    double **A;
    initialize(A, 10, 10);
 ......
}

void initialize(double **A, int r, int c)
{
   A = (double **)malloc(sizeof(double *)*r);
   for(int i = 0; i< r; i++) {
        A[i] = (double *)malloc(sizeof(double) *c);
        for(int j = 0; j < c; j++) {
            A[i][j] = 0.0;
        }
   }
}

如何将双指针传递给函数.....

【问题讨论】:

  • 如果不更改初始化将无法编译 -- &amp;Adouble***

标签: c function segmentation-fault


【解决方案1】:

如果要修改指向指针的指针,则需要将指向指针的指针传递给指针。

void func(double ***data) { *data = malloc(sizeof(double*)*10); for.... };
double ** data; func(&data);

【讨论】:

  • 刚刚重温我的C:如果你想修改C中的一个指针,你需要将一个指针传递给一个指针。如果需要修改指向指针的指针,则需要传递指向指针的指针。为什么?那么我们可以说,如果我们想修改一个值,我们还需要传递一个指向该值的指针吗?请进一步解释。提前致谢。
  • 总而言之,可以说如果要修改函数内部的值,则需要将指向该值的指针传递给函数。值(总是)只是(按值)复制到函数中。 Example/Reference
【解决方案2】:

一方面,初始化内部的AmainA 的副本——所以当您返回main 时,它的A 仍未初始化。如果你尝试并使用它——砰!

要将其传递给initialize'by reference',需要将参数类型更改为double***,并在main 中传入&amp;A。那么,在initialize中使用的时候,每次都需要解引用,即*A

【讨论】:

    【解决方案3】:
    1. 您没有检查内存不足错误。失败。

    2. 您通过 BY VALUE 将未初始化的值 A 传递给 initialize(),然后对其进行初始化。但回到 main() 中,局部变量 A 仍未初始化。相反,您可能让 initialize() 返回 double**(例如 A = initialize(...))或修改 initialize(),使其第一个形式参数是您使用 *pA = (double**)malloc(...); 初始化的 double ***pA

    【讨论】:

    • 回复。 (1),公平点,但有多少像这样的玩具程序内存不足?
    • 那么,您是要建议初学者检查内存不足的情况,还是要他们学习编写脆弱的软件?不。如果他想将A初始化为initialize()的out参数,他需要传入一个double***,然后在原始A出现的任何地方都将其用作(*pA)
    【解决方案4】:

    正如其他人所说,您需要在 init 函数中获取指向指针的指针。 initialize 函数是这样变化的:

    void initialize(double ***A, int r, int c)
    {
       *A = (double **)malloc(sizeof(double *)*r);
       for(int i = 0; i< r; i++) {
            (*A)[i] = (double *)malloc(sizeof(double) *c);
            for(int j = 0; j < c; j++) {
                (*A)[i][j] = 0.0;
            }
       }
    }
    

    main 将是:

    int main()
    {
        double **A;
        initialize(&A, 10, 10);
    }
    

    此外,您发布的代码在传递A 指针时应该不会导致分段错误。分段错误最有可能发生在您从函数返回并尝试访问A 时,因为Amain 中不会被初始化。只有一个副本以您的方式初始化,并且该副本是 initialize 函数的本地副本,因此在您返回时它会丢失。

    【讨论】:

    • @LVlad 嗨,很好的答案。重温一下我的 C:如果要修改 C 中的指针,则需要将指针传递给指针。如果需要修改指向指针的指针,则需要传递指向指针的指针。为什么?那么我们可以说,如果我们想修改一个值,我们还需要传递一个指向该值的指针吗?请进一步解释。提前致谢。
    • HI Unheilig,这与引用调用有关。例如(某种类型)*A 那么如果需要在当前定义 A 的地方以外的地方修改某些类型,则必须传递 A 的地址,并且需要在被调用函数中取消引用传递的地址。传递地址的原因是被调用函数在进程地址空间中获得了它的单独堆栈。在上面的问题中,在 main() 中定义的 A 位于单独的堆栈中,并且永远不会被 initialize() 访问。如果在 main() 中没有回访 A,则没有报错。
    • 非常感谢,我为此苦苦挣扎了 3 天。
    【解决方案5】:

    这是你不想做的事情。不要为此不必要地使用 out 参数,而是在函数中分配并返回结果。改为这样做:

    int main() 
    {
        double **A;
        A = initialize(A10, 10);
    }
    
    double** initialize(int r, int c)
    {
       double **A;
       A = malloc(sizeof(double *)*r);
       for(int i = 0; i< r; i++) {
            A[i] = (double *)malloc(sizeof(double) *c);
            for(int j = 0; j < c; j++) {
                A[i][j] = 0.0;
            }
       }
      return A;
    }
    

    【讨论】:

    • 您忘记更新initialize的返回类型,并实际返回一个值。
    猜你喜欢
    • 2012-02-05
    • 2014-06-20
    • 2020-12-17
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    • 2017-08-30
    • 1970-01-01
    • 2011-04-17
    相关资源
    最近更新 更多