【问题标题】:Updating 2D Array in C在 C 中更新二维数组
【发布时间】:2014-10-23 05:39:47
【问题描述】:

我必须遍历 2d 数组的每个索引并找到相邻值是什么,然后根据该值更新数组的索引。我下面的代码完成了所有这些操作,但是当我必须更新数组时,它会更新现有数组,因此下一个索引会产生不正确的输出。我尝试创建一个新数组,但是当我使用新数组时,没有任何更新并且它保持不变。这就是我现在所拥有的。

void ch(int **b, int w, int h)
{
    int x,y,i,ct=0;
    int **up;
    up=malloc(sizeof(int *) * h);
    for(i = 0; i<h; i++){
        up[i]=malloc(sizeof(int)*w);
    }

    for (x=0;x<h;x++)
    {
        for(y=0;y<w;y++)
        {
            //...Computes Count Here(It Works)
            //UPDATE BOARD - Does not update the board
            if(b[x][y]==1 && ct<2)
            {
                up[x][y]=0;
            }
            else if(b[x][y]==1 && (ct==2 || ct==3))
            {
                up[x][y]=1;
            }
            else if(b[x][y]==1 && ct>3)
            {
                up[x][y]=0;
            }
            else if(b[x][y]==0 && ct==3)
            {
                up[x][y]=1;
            }
            ct=0;
        }
    }
    b=up;
}

我尝试通过对其自身进行更改来更新二维数组 b,它会更改数组,但它不是我要查找的输出。它会在每次迭代时更改输出,因此其他索引的输出会发生更改,但我想要它以便另一个数组跟踪输出,以便它不会在每次迭代时更新 b 并给出正确的输出。我做错了什么不让我更新?解决此问题的最佳方法是什么?

【问题讨论】:

  • count 定义在哪里?
  • @JoelCornett 抱歉,这是一个错字。我的意思是ct。更新了代码!
  • 您没有else 子句来捕捉不可能的事情。也许不可能的事情发生得太频繁了?
  • 也许你应该尝试在函数中打印up;这会告诉你它正在被设置(或没有)。您应该返回新数组——创建函数char **ch(int **b, int w, int h) { …; return up; }。或者,您必须使用三重指针参数,并对代码进行一些调整。请注意,如果覆盖原始数组指针,则必须担心内存泄漏。

标签: c arrays multidimensional-array


【解决方案1】:

复制原始数组并将其用作参考。然后你可以直接更新你原来的数组。

void ch(int **b)
{
   int **up = malloc(sizeof(*int)*h);
   int i;
   for (i = 0; i < w; i++)
   {
       up[i] = malloc(sizeof(int) * w);
       memcpy(up[i], b[i], w * sizeof(int));
   }
   //
   if (up[x][y] == 1)
       b[x][y] = 0;
}
// free up

这可能比在

中具有额外的间接级别更容易维护
void ch(int ***b)
{
   int **up = *b;
   // do everything else as you intended

   // finalize with
   *b = up;
   // free up
}

此外,在制作副本时,您可以通过将临时副本分配为线性数组来稍微提高性能

int *up = malloc(sizeof(int) * w * h);

if (up[y * w + x] == 0)
    b[y][x] = 1;

【讨论】:

  • 这行得通,但我不认为我可以使用 memcpy。有没有办法可以复制数组而不将其链接到 b?
  • 在这种情况下使用线性化数组:for (i=0; i&lt;w; i++) for (j=0;j&lt;h;j++) up[i*w+j]=b[i][j];
【解决方案2】:

C 按值传递参数

所以你可以这样做

int* pass(int *p){

//return new pointer; and later assign
}

或获取地址

void pass(int **p)
{
 *p=//new pointer

}

对于您的情况,最好在不分配新的情况下修改内部相同的数组

我不能修改同一个数组

您可以按照建议处理数组副本,然后从副本更新先前的数组

或者按照我的建议返回那个复制的数组

值得一看:

C Faq question related on your issue

C Faq ways for allocating multidimensional array

【讨论】:

  • new 不是 C 而是 C++
  • 我不打算新的。
  • 我不能修改同一个数组,因为它会搞砸我的计数来修改下一个索引。这就是为什么我必须创建一个新数组。
  • 返回那个指针。与第一种情况一样。并且不要忘记你必须在使用后释放返回的指针
  • 我无法更改返回类型。它必须是无效的。我必须让它无效,我正在释放 main 中的所有内容。
【解决方案3】:

在你的函数末尾,你有b=up;,你设置b指向你的新数组,但这只会改变你函数的副本(b),而不是调用函数中的副本。 . 所以调用者仍然看到原始数组。

但是,由于您使用的是指向数组的指针数组,而不是实际的二维数组,您可以替换 bcontents(@987654325 @'s 到构成附加维度的数组)...这样可以避免将所有新数组的数据复制到原始数组中。

所以而不是:

b=up;

尝试:

for(i = 0; i < h; i++) {
    free(b[i]);
    b[i] = up[i];
}
free(up);

这样,通过更改原始行数组中的指针,原始数组的每一行都会被新行中的相应行替换。

这只是一个好主意,但是,如果原始数组的行像新数组中的行一样动态分配,并且没有其他指向浮动的行的指针(在行数组之外以b) 传递,之后可能仍指向旧内存。

【讨论】:

  • 打印出一些 int 值的内存地址。
  • 原始数组的声明是什么样子的?它是否像 up 在您的函数中一样创建?
  • 是的。完全一样。
  • 我看不出你可以从我建议的更改中将指针值获取到行数据中。除非wh 落后……
猜你喜欢
  • 1970-01-01
  • 2015-06-11
  • 2021-10-31
  • 2014-05-30
  • 1970-01-01
  • 1970-01-01
  • 2012-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多