【发布时间】: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