【问题标题】:Questions about the multi-dimension array in Java and C#?关于 Java 和 C# 中的多维数组的问题?
【发布时间】:2012-02-06 15:03:33
【问题描述】:

在Java或C#编程语言中,我们可以像下面这样声明多维数组:

int[][] arr = new int[2][];
arr[0] = new int[3];
arr[1] = new int[4];

我想知道代码里面的内存分配机制,尤其是它们和C编程语言的区别?

【问题讨论】:

  • 好奇固然很好,但你为什么想知道呢?
  • 内存分配机制是什么意思?您应该了解的一件事是 C#,Java 在虚拟运行时上运行,而 C 被编译为本机。虚拟机使用与编译代码相同的调用。所以这三者的实际内存分配是相同的。但是在运行时,它们有不同的内存分配机制..
  • 对于使用的内存大小,请检查 C# 中称为 sizeof 的方法
  • C 中的内存分配机制大致相同。唯一的区别是 C 既支持指向数组的指针数组,也支持数组或数组。 Java 和 C# 支持对数组的引用数组。

标签: c# java c multidimensional-array


【解决方案1】:

在 Java 中,所有这些分配都在堆上,因此您的代码与 C 代码相同:

int **arr=malloc(2*sizeof(int*));
arr[0]=malloc(3*sizeof(int));
arr[1]=malloc(4*sizeof(int));

编辑:我不是 Java 专家,但我认为在 Java 中,新数组的成员被初始化为 0(或 null),所以 calloc 比 malloc 更正确(在我的代码中)。

【讨论】:

    【解决方案2】:

    我只能从 Java 的角度谈谈,但我相信 C# 的工作方式大致相同(如果不是这种情况,请有人纠正我)。

    声明和分配数组与在执行的哪个时间点做了什么是有区别的。

    当你声明一个数组类型的变量时,它持有一个对象的引用。这不会创建数组对象或为其组件分配空间,只是变量本身。但是初始化器可以创建一个数组,然后它成为变量的初始值。例如:

    //only has a variable of firstArray (i.e. doesn't create array,
    //therefore array memory not used)
    
    int[] firstArray; 
    
    //creates variable secondArray and allocates 4 int
    //values to the array
    
    int[] secondArray = { 1, 2, 3, 4 }; 
    

    参考:(§10.2) JLS

    当分配的数组没有特定值时,所有元素都会接收到数组数据类型的默认值(例如,对于布尔值,它将为 false,对于 int 为 0 等)例如:

    //Creates an array of 5 Object's which will all
    //be null.
    
    Object[] objectArray = new Object[5];  
    

    参考:(§8.3) & (§10.2)JLS

    这里还有一些多维数组的例子:

    //This is allocating an int[] array inside myArray at position [0]
    int[][] myArray = { { 1, 2 } };
    
    for (int[] i : myArray)
        for (int j : i)
          System.out.println(j);  //will print 1 then 2;
    

    使用你的一个例子:

    //This is declaring a multi-dimensional array of int with a max length of 2
    int[][] arr = new int[2][]; //Only declaration, no memory allocation for array components
    
    arr[0] = new int[] {1, 2};  //Allocating memory
    arr[1] = new int[] {3, 4};  //Allocating memory
    
    for(int[] i : arr)
      for(int j: i)
        System.out.println(j);  //Will print 1 then 2 then 3 then 4...
    

    【讨论】:

      【解决方案3】:

      这不是一个完整的答案,但 Java 虚拟机有自己的分配多维数组的指令。请参阅The Java Virtual Machine Specification 中的 multianewarray。

      如果您调用new int[1][2][],编译器会生成字节码,其中包含multianewarray 指令,维度为1 和2,类型为int[][][]。

      【讨论】:

        【解决方案4】:

        由于您使用常量,编译器(应该)将所有请求合并到一个分配中,并简单地在可执行文件本身(.bss 部分)中创建一个静态块来为数组保留内存。对于动态分配,可能(在幕后)使用 malloc 为数组分配内存。对于动态大小的数组,诸如 C# 和 Java 之类的语言还有其他需要存储的元数据,例如大小,所以我无法准确告诉您它将使用多少内存。我相信静态大小的数组也需要调整大小,因为运行时边界检查。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-02-09
          • 2020-05-18
          • 2011-07-15
          • 2018-01-05
          • 2020-07-20
          相关资源
          最近更新 更多