我有一个变量N
。我需要一个6xNxN
数组。
这样的事情:
int arr[6][N][N];
但是,显然,这不起作用。
我不知道我是如何分配这个以便我可以访问的,例如如果arr[5][4][4]
为5,则N
;如果arr[5][23][23]
为24,则为N
。
请注意N
永远不会改变,所以我永远不必realloc
吃arr
。
我该怎么办? int ***arr = malloc(6 * N * N * sizeof(int));
会工作吗?
答案 0 :(得分:3)
您可以在堆上分配三维数组
int (*arr)[N][N] = malloc(sizeof(int[6][N][N]));
使用后,您可以免费
free(arr);
另一种写@StoryTeller建议的方式是 -
int (*arr)[N][N] = malloc(6u * sizeof(*arr));
但是在这里你需要注意u
之后的6
以防止签名的算术溢出。
此外,@ {qqrlie建议size_t
宽度小于int
的平台仍然存在问题,但大多数" #34;常用的平台因此你可以使用它。
答案 1 :(得分:2)
int arr[6][N][N];
可以正常使用。您只需将编译器和C知识更新到1999或更高版本,当时将可变长度数组(VLA)引入该语言。
(如果您的GCC版本低于5.0,则必须通过传递-std=c99
或-std=c11
明确告诉它不要使用古老版本的C标准。)
或者,如果您需要堆分配,则可以执行以下操作:
int (*arrptr)[Y][Z] = malloc( sizeof(int[X][Y][Z]) );
由于int ***arr = malloc(6 * N * N * sizeof(int));
无法指向3D数组,因此您无法执行int***
。一般来说,两个以上的间接水平是一个标志,表明你的程序设计是完全有缺陷的。
答案 2 :(得分:1)
你想要什么不能直接工作。对于索引多维数组,除了第一个维度之外的所有维度都必须是类型的一部分,这就是原因:
索引操作符对指针进行操作,方法是首先向指针添加索引,然后取消引用它。数组的标识符计算为指向其第一个元素的指针(例如,与sizeof
,_Alignof
和&
一起使用时除外),因此对数组的索引按预期工作。
在单维数组的情况下,它非常简单。随着
int a[42];
a
求值为int *
类型的指针,索引的工作方式如下:a[18] => *(a + 18)
。
现在在一个二维数组中,所有元素都是连续存储的(如果你想把它理解为一个矩阵,那么“row”之后的“row”),以及使索引“魔术”起作用的是类型涉及。举个例子:
int a[16][42];
这里,a
的元素的类型为int ()[42]
(int元素为42个元素)。根据上面的规则,在大多数上下文中再次计算此类型的表达式会产生int *
指针。但是a
本身呢?好吧,它是int ()[42]
的数组,因此a
将评估为指向int 的42个元素数组的指针:int (*)[42]
。然后让我们看一下索引操作符的作用:
a[3][18] => *(*(a + 3) + 18)
a
评估a
类型为int (*)[42]
的地址,3
的内部添加可以正确添加42 * sizeof(int)
。如果类型中未知第二维度,则无法进行此操作。
我想推断出n维案例的例子很简单。
在您的情况下,您有两种可能性来实现类似于您想要的东西。
使用大小为6*N*N
的动态分配的 flat 数组。如果您在某处保存N
,则可以自己计算指数。
效率稍差,但产生更好的可读代码,你可以使用指向int (多个间接)指针数组的指针数组。你可以,例如做
int ***a = malloc(6 * sizeof *int);
for (size_t i = 0; i < 6; ++i)
{
a[i] = malloc(N * sizeof *(a[i]));
for (size_t j = 0; j < N ++j)
{
a[i][j] = malloc(N* sizeof *(a[i][j]));
}
}
// add error checking to malloc calls!
然后你的访问看起来就像那些普通的3d数组一样,但它存储在内部尽可能多的数组,指针指向其他数组而不是大的连续块。
我不认为使用这么多的间接是值得的,只是为了避免写例如: a[2*N*N+5*N+4]
访问2,5,4
处的元素,因此我的建议是第一种方法。
答案 3 :(得分:0)
对此行中的声明进行简单更改并保留<widget id="com.ionicapp.yournewapp" version="0.0.1" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>thisis the name that needs to replaced</name>
<!-- Content removed for brevity -->
</widget>
可以轻松解决您的问题。
malloc
但是,int ***arr = malloc(6 * N * N * sizeof(int));
是不必要的(而且是错误的)。使用易于分配的平面阵列:
int ***
这适用于三个维度,而不是像问题一样访问int *flatarr = malloc(6 * N * N * sizeof(int));
,而是访问arr[X][Y][Z]
。事实上,你甚至可以写一个方便的宏:
flatarr[(X*N*N) + (Y*N) + Z]
这基本上是我用我的语言Cubically完成的,以允许使用多个大小的多维数据集。感谢Programming Puzzles & Code Golf用户Dennis给了我这个想法。