分配6xNxN阵列

时间:2017-08-09 03:57:23

标签: c arrays memory multidimensional-array malloc

我有一个变量N。我需要一个6xNxN数组。

这样的事情:

int arr[6][N][N];

但是,显然,这不起作用。

我不知道我是如何分配这个以便我可以访问的,例如如果arr[5][4][4]为5,则N;如果arr[5][23][23]为24,则为N

请注意N永远不会改变,所以我永远不必reallocarr

我该怎么办? int ***arr = malloc(6 * N * N * sizeof(int));会工作吗?

4 个答案:

答案 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***。一般来说,两个以上的间接水平是一个标志,表明你的程序设计是完全有缺陷的。

此处的详细信息:Correctly allocating multi-dimensional arrays

答案 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维案例的例子很简单。

在您的情况下,您有两种可能性来实现类似于您想要的东西。

  1. 使用大小为6*N*N的动态分配的 flat 数组。如果您在某处保存N,则可以自己计算指数。

  2. 效率稍差,但产生更好的可读代码,你可以使用指向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给了我这个想法。