【问题标题】:A different way to malloc a 2D array?malloc 二维数组的另一种方法?
【发布时间】:2013-06-27 15:52:34
【问题描述】:

我想使用 malloc 声明一个二维数组。在互联网上查找时,所有网站都告诉声明一个 int ** 指针,然后使用 malloc 首先将各个指针分配给一维数组,然后再次使用 malloc 为各个 int 分配空间。我怀疑以这种方式声明的数组不会将其元素保存在连续的内存地址中。而以下方式仅使用一个 malloc 语句并动态分配一个二维数组,并且所有地址都根据需要是连续的。那么以下不应该是动态分配二维数组的正确方法吗?

#include <stdio.h>

int main(){
    int (*p)[2] = malloc(3 * sizeof *p);
    int i;
    int j;

        //All addresses printed here are contiguous
    for(i=0; i<3; i++){
        for(j=0; j<2; j++){
            printf("%d\t", &p[i][j]);
        }
        printf("\n");
    }
}

【问题讨论】:

  • 这是分配二维数组的正确方法;您之前描述的是一个锯齿状数组,但是,如果您不存储各个子数组的长度,那么它几乎没有用;将幻数 24 更改为 3 * sizeof *p 就可以了
  • 您不应该使用%d 打印指针,但有%p 用于此目的,并且为了完全可移植性,您还必须转换为void*
  • 为什么在引用数组元素时使用&amp;p?是否打算检查地址而不是值?

标签: arrays c multidimensional-array malloc


【解决方案1】:

那么下面不应该是动态分配二维数组的正确方法吗?

应该,因为这种方法相当于声明一个“静态分配”的多维数组。

这样做的原因是这样,你得到一个连续的内存块,这很方便(你不能在指针上使用memset(),对吧?),你仍然可以拥有编译器为你做指针算术和数组下标计算(也很方便)。

顺便说一句,如果您需要一个动态大小的数组,其范围仅在一个函数内,即。 e.您不需要返回它,请考虑使用具有自动存储持续时间的 VLA(可变长度数组)。

【讨论】:

    【解决方案2】:

    您的二维数组不是完全动态的,因为它的一个维度固定为两个元素。 (在您的特定示例中,您可以使用可变长度数组,但通常您可能希望能够从函数返回分配的数组。)

    如果你想要在语法上表现得像 2D M×N 数组的东西,完全动态分配,并使用连续内存,你可以分配一块内存 M * N 元素,然后分配M 指针数组,其中每个元素指向M * N 块的“行”。

    Q6.16 from the comp.lang.c FAQ 有一个很好的图表和更详细的解释。

    (好吧,它不是完全连续的,因为指针数组和项目块是分开的。你可以将它们一起分配,尽管这更棘手,因为它需要一些额外的工作来保证正确对齐。)

    【讨论】:

    • 维度不固定,因为问题代码中显示的2 不必是常数。自 1999 年以来,C 标准就支持可变长度数组。任何具有正值的整数表达式都可以使用,即使它的值仅在运行时可用。
    • @EricPostpischil 是的,我知道 VLA,但函数无法返回它,所以它不是很通用。我已经更新了我的答案来解释这一点。
    • 如果调用者不知道尺寸,那么无论如何您都需要 2 或 3 个输出,因此您不能只返回一个指针。您可以通过引用作为输出参数返回行长(如果非正方形,则为行数),并让调用者转换返回的指针。您可能需要将其保存在void* 中,以便调用者可以在声明指向数组的指针返回值的类型之前获得维度,但可以将指向二维数组的指针传递与他们的维度,同样地接受他们。
    【解决方案3】:

    换句话说:

    include < stdio.h>
    include < stdlib.h>
    const int **MAXX** = 10 ;
    const int **MAXY** = 10 ;
    int main () {
     int *p = ( int * ) malloc ( **MAXX * MAXY** ) ;
     int x=3 ;
     int y=4 ;
     ***( p + MAXX * x + y )** = 12 ;
     printf ( "\n%d ",***( p + MAXX * x + y )** );
     return 0 ;
    }
    

    这是分配和使用二维数组的最简单方法

    【讨论】:

    • 我强烈建议您从答案中删除那些额外的*s。它们只是使代码难以理解且无法编译。
    • (1) 自 1999 年以来,可变长度数组一直在 C 标准中,应该使用它们而不是明确表达的算术。 (2)malloc(MAXX*MAXY)不为MAXX*MAXYint对象分配空间。
    猜你喜欢
    • 1970-01-01
    • 2022-01-03
    • 2011-10-30
    • 1970-01-01
    • 1970-01-01
    • 2013-11-30
    • 1970-01-01
    • 2017-12-13
    • 2021-06-04
    相关资源
    最近更新 更多