【问题标题】:Multidimensional arrays in CC中的多维数组
【发布时间】:2013-03-21 22:46:22
【问题描述】:

我对这个问题的回答与cmets有关:How to turn 2d array out of 1d one?

所以,考虑一下这个 sn-p:

int M = 5;
int N = 5;

int** theArray = (int**) malloc(M*sizeof(int*));  

for (int i = 0; i < M; i++)
{
    theArray[i] = (int*) malloc(N*sizeof(int));

    for(int j = 0 ; j < N; j++)
    {
        theArray[i][j] = i+j;
        printf("%d ", theArray[i][j]);
    }

    printf("\n");
}

for (int k = 0; k < M; k++)
{  
   free(theArray[k]);  
}
free(theArray);

我得说它在我的机器上运行得非常好,但我在 cmets 中被告知这纯粹是运气,声明二维数组的方法是错误的,应该只分配 1 个 malloc 来获得连续的内存记忆。

我真的很困惑,因为我认为 C 中的非动态多维数组的工作方式完全相同:它们基本上是一个指针数组,其中每个值都是一个数组。

问题是,这样做是否正确(便携式、常见做法等)?我错过了有关此主题的内容吗?我的意思是,我真的看不出这段代码有什么问题。

编辑:

我从 WhozCraig 和 Daniel Fischer 的 cmets 那里得到了我终于明白的答案。我的主要错误是我认为数组和指针比实际更相似。

主要原因是实际多维数组存储在线性内存中的行优先顺序 (http://en.wikipedia.org/wiki/Row-major_order)。为了理解真正的多维数组和我的片段之间的实际区别,我建议阅读这篇文章(它为我很好地阐明了这个主题,并提供了易于理解的示例):

第 1 部分:http://eli.thegreenplace.net/2009/10/21/are-pointers-and-arrays-equivalent-in-c/

第 2 部分:http://eli.thegreenplace.net/2010/04/06/pointers-vs-arrays-in-c-part-2d/

【问题讨论】:

  • 您认为非动态多维数组与指向数据指针的指针同义是完全不正确的。也就是说,您的代码没问题,只要 theArray 从未传递给声明为接受类似于 int ar[][N] 的参数的函数。它们绝对相同。有几篇优秀的帖子讨论了 C/C++ 中的多维数组工作。我会尝试追捕他们,但建议你也这样做。他们中的一些人在他们的 ascii-art 视觉效果中 惊人 =P
  • WhozCraig 所说的。你的代码很好,但你分配的不是多维数组。
  • 所以,关键是代码是正确的,但从技术上讲,它只是作为“接口”的多维数组,但它并不是真正的多维数组,对吧?感谢您的回答,要去阅读指针与数组之类的东西,看来我对这个主题的了解是错误的:)
  • 我认为第一篇文章对你来说是旧闻。但是第二个很好地说明了如何使用指针到指针来模仿 C 中的多维数组。请注意,int** 方法确实 提供真正多维数组不提供的一件事是可变行宽。并非所有行都必须使用像您这样的代码具有相同的宽度(显然您最好知道在这方面您在做什么)。另外,虽然那篇文章最后只是简单地谈到了它,int (*ar)[N] 也很常见,我建议编写一些代码来看看它们是如何工作的。它可以具有教育意义。

标签: c arrays memory-management multidimensional-array


【解决方案1】:

比较这段代码:

int array[10][10];

for (int i = 0; i < 10 * 10; i++) {
   *((int *)array+i) = 0;
}

这对于二维数组来说很好,因为所有内存都是连续的。在您的版本中,您有一组连续的指针,每个指针都可以指向内存中的任何位置。

【讨论】:

  • 是的,我知道非动态分配的数组在内存中是连续的。问题是有人告诉我,我的代码完全不正确,结果证明是错误的 - 从技术上讲,它不是一个多维数组(也许我在链接问题中让评论者错了,也许他是认真的)。从 WhozCraig 和 Daniel Fischer cmets 那里得到了这个问题。
  • @StanMcGeek - 你的代码是正确的还是完全不正确的取决于你想用它做什么:) 如果你把它当作一个多维数组,在许多情况下你会得到一个段错误,在其他的就好了。
猜你喜欢
  • 1970-01-01
  • 2014-06-20
  • 2016-12-07
  • 2023-03-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多