在递归函数中通过引用传递的数组 - 最后一列重新初始化

时间:2013-01-22 20:45:44

标签: c++ c

我的一个功能有一个相当意外的问题。让我解释。 我正在编写校准算法,因为我想做一些网格搜索(非连续优化),我正在创建自己的网格 - 不同的概率组合。 网格的大小和网格本身的计算是递归(我知道......)。 所以按顺序:

  1. 获取变量
  2. 递归计算相应的大小
  3. 为网格分配内存
  4. 通过引用传递空网格并递归填充
  5. 我遇到的问题是在尝试检索此网格后的第4步之后。在第4步中,我在控制台上“打印”结果以检查它们,并且一切都可以。我用几个变量计算了几个网格,它们都符合我期望的结果。但是,一旦网格从递归函数中取出 last 列将填充0(之前的所有值仅在此列中替换)。 我尝试在步骤3中为网格分配一个额外的列,但这只会使问题变得更糟(-3e303等值)。我也有错误,无论我用它计算它的大小(非常小到非常大),所以我认为它不是内存错误(或者至少是'缺少内存'错误)。最后使用的两个函数和它们的调用已在下面列出,这已被快速编程,因此一些变量似乎没用 - 我知道。但是我总是对你的意见持开放态度(加上我不是C ++的专家 - 因此这个主题)。

    void size_Grid_Computation(int nVars, int endPoint, int consideredVariable, int * indexes, int &sum, int nChoices)
    {
    /** Remember to initialize r at 1 !! - we exclude var_0 and var_(m-1) (first and last variables) in this algorithm **/
     int endPoint2 = 0;
    
     if (consideredVariable < nVars - 2)
     {
        for (indexes[consideredVariable] = 0; indexes[consideredVariable] < endPoint; indexes[consideredVariable] ++)
        {
            endPoint2 = endPoint - indexes[consideredVariable];
            size_Grid_Computation(nVars, endPoint2, consideredVariable + 1, indexes, sum, nChoices);
        }
    
     }
     else
     {
        for (int i = 0; i < nVars - 2; i++)
        {
            sum -= indexes[i];
        }
        sum += nChoices;
        return;
    
     }
    }
    

    以上功能适用于网格尺寸。下面是网格本身 -

    void grid_Creation(double* choicesVector, double** varVector, int consideredVariable, int * indexes, int endPoint, int nVars, int &r)
    {
     if (consideredVariable > nVars-1)
        return;
     for (indexes[consideredVariable] = 0; indexes[consideredVariable] < endPoint; indexes[consideredVariable]++)
     {
    
        if (consideredVariable == nVars - 1)
        {   
            double sum = 0.0;
            for (int j = 0; j <= consideredVariable; j++)
            {
                varVector[r][j] = choicesVector[indexes[j]];
                sum += varVector[r][j];
                printf("%lf\t", varVector[r][j]);
            }
            varVector[r][nVars - 1] = 1 - sum;
            printf("%lf row %d\n", varVector[r][nVars - 1],r+1);
            r += 1;
    
        }
        grid_Creation(choicesVector, varVector, consideredVariable + 1, indexes, endPoint - indexes[consideredVariable], nVars, r);
     }
    
    }
    

    最后通话

    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
     int nVars = 5;
     int gridPrecision = 3;
    
    
    int sum1 = 0;
    int r = 0;
    
    int size = 0;
    int * index, * indexes;
    
    index = (int *) calloc(nVars - 1, sizeof(int));
    indexes = (int *) calloc(nVars, sizeof(int));
    
    for (index[0] = 0; index[0] < gridPrecision + 1; index[0] ++)
    {
        size_Grid_Computation(nVars, gridPrecision + 1 - index[0], 1, index, size, gridPrecision + 1);
    }
    
    double * Y;
    
    Y = (double *) calloc(gridPrecision + 1, sizeof(double));
    
    for (int i = 0; i <= gridPrecision; i++)
    {
        Y[i] = (double) i/ (double) gridPrecision;
    }
    
    double ** varVector;
    
    varVector = (double **) calloc(size, sizeof(double *));
    
    for (int i = 0; i < size; i++)
    {
        varVector[i] = (double *) calloc(nVars, sizeof(double *));
    }
    
    
    
    grid_Creation(Y, varVector, 0, indexes, gridPrecision + 1, nVars - 1, r);
    for (int i = 0; i < size; i++)
    {
        printf("%lf\n", varVector[i][nVars - 1]);
    }
    }
    

    我离开了我的野蛮人'printf',他们帮助缩小了问题的范围。最有可能的是,我已经忘记或屠杀了一个内存分配。但我看不出哪一个。无论如何,谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

在我看来,你有一个主要的错误设计,即你的2D阵列。你在这里编程的是不是 2D数组,而是它的模拟。只有你想要一种稀疏的数据结构才能省略部分才有意义。在你的情况下,它看起来好像只是一个你需要的普通旧矩阵。

现在,在C和C ++中都不适合这样编程。

在C中,因为这看起来就是你所追求的内部函数,你甚至用动态边界声明矩阵

double A[n][m];

如果你担心这会粉碎你的“堆叠”,你可以动态分配它

double (*B)[m] = malloc(sizeof(double[n][m]));

通过将边界首先放在参数列表

中,将这些野兽传递给函数
void toto(size_t n, size_t m, double X[n][m]) {
 ...
}

一旦你有清晰易读的代码,你就会发现你的错误更容易。