在递归函数中通过引用传递的数组 - 最后一列重新初始化
Array passed by reference in recursive function - last column reinitialized
我的一个函数遇到了一个相当意外的问题。让我解释一下。我正在编写一个校准算法,由于我想做一些网格搜索(非连续优化),我正在创建自己的网格 - 不同的概率组合。网格的大小和网格本身是递归计算的(我知道......所以按顺序:
- 获取变量
- 递归计算相应的大小
- 为网格分配内存
- 通过引用传递空网格并递归填充它
我遇到的问题是在步骤 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("%lft", varVector[r][j]);
}
varVector[r][nVars - 1] = 1 - sum;
printf("%lf row %dn", 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("%lfn", varVector[i][nVars - 1]);
}
}
我离开了我的野蛮人"printf",他们帮助缩小了问题的范围。最有可能的是,我忘记或屠杀了一个内存分配。但我看不出是哪一个。无论如何,感谢您的帮助!
在我看来,您有一个主要的错误设计,即您的 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]) {
...
}
一旦你有了干净和可读的代码,你会发现你的错误要容易得多。
- 查找矩阵C++中每一列和每一行的最小和最大元素
- 如何在C++中获取二维数组中最少的一列数?
- 如何在最后一步使用CryptDecrypt解决NTE_BAD_DATA
- 如何检测是否在缓冲绘画动画中绘制最后一帧?
- 斐波那契数列部分和的最后一位数字
- std::ifstream 在读取文件中最后一项时设置 eofbit,但仅在读取数值类型时发生
- 将第 n 个斐波那契数的大斐波那契数的最后一位编程.C++
- 经过最后一个数组元素末尾的指针是否应该等于超过整个数组末尾的指针?
- foor 循环的最后一次迭代中的指针更改
- 访问类成员向量最后一项的正确方法
- 从函数参数包中删除最后一项
- 如何允许用户选择何时停止三列中的每一列的旋转
- 从我的2d数组中的一列返回的字符串值被压缩为一个字符串(在Mac os上打开Windows txt文件)
- C++ 查找算法:如何找到元素的最后一次出现?
- 为什么当 while 循环中的 if 条件变为 false 时,我的函数不输出最后一条语句?
- C++ 最后一列中的直方图错误
- 我在一个简单控制台程序(c++)中的第一列代码最终成为我的最后一列
- 如何擦除前 7 列加上最后一列,第 9 列,仅将第 8 列留在 3d 矢量中,例如 vector<vector<pair<int,int>>>?
- 在递归函数中通过引用传递的数组 - 最后一列重新初始化
- 从输入文件的最后一列决定一个例程