2

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

  1. 获取变量
  2. 递归计算对应大小
  3. 为网格分配内存
  4. 通过引用传递空网格并递归填充

一旦我尝试检索此网格,我遇到的问题是在第 4 步之后。在第 4 步中,我在控制台上“打印”结果以检查它们,一切都很好。我计算了几个带有几个变量的网格,它们都与我期望的结果相匹配。然而,一旦网格从递归函数中取出,最后一个列用 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',他们帮助缩小了问题范围。很可能,我忘记或破坏了一个内存分配。但我看不出是哪一个。无论如何,感谢您的帮助!

4

1 回答 1

1

在我看来,你有一个主要的错误设计,即你的二维数组。你在这里编程的不是二维数组,而是它的仿真。仅当您想要一种稀疏数据结构时才有意义,您可能会遗漏部分。在您的情况下,它看起来好像只是您需要的普通旧矩阵。

如今,在 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]) {
 ...
}

一旦你有干净和可读的代码,你会发现你的错误更容易。

于 2013-01-22T21:44:47.073 回答