C/C++与Java二维数组的内存分配区别

3 篇文章 0 订阅

今天在学习JAVA二维数组时,发现和C++二维数组分配不同:

JAVA中, 定义了一个二维数组arr[3][4],输出arr和arr[0]发现两个地址不一样。

而对于C++来说应该是一样的。所以这就涉及到两种语言二维数组的内存分配的区别。

找到一篇比较清楚的blog(来自博主忆之独秀):




Java二维数组的内存结构图:

今天看了个视频,说Java中二维数组是这样的:java中的二位数组是按维存储的。


 
在Java中是可以这样的,二维数组有三种定义格式!
定义格式1:
定义格式1的内存图:

 
 
定义格式2:
 
定义格式2的内存结构图:

 
 
定义格式3:
定义格式3内存图:

C语言二维数组的内存结构图:
 
突然,感觉和自己脑海中C的不一样。还专门去看了下C的。
[cpp]  view plain  copy
  1. void main()  
  2. {  
  3.     int a[3][2];  
  4.     cout << a <<"\t"<< &a << endl<<endl;  
  5.       
  6.     cout << a[0] << "\t" << a[1] << "\t" << a[2] << endl << endl;  
  7.   
  8.     cout << &a[0][0] << "\t" << &a[0][1] << endl << endl;  
  9.     cout << &a[1][0] << "\t" << &a[1][1] << endl << endl;  
  10.     cout << &a[2][0] << "\t" << &a[2][1] << endl << endl;  
  11.   
  12. }  

 
运行结果:


也就是说,C语言的二维数组确实是下面这样:
,C语言的二维数组是连续一维存储的。



所以这就让我明白了,Java的二维数组和一维数组的内存其实是分开分配的,而C++中二维数组的内存其实就是一维数组的内存所组成的。
而且,C++中在定义二维数组时:只允许int arr[][3]={1,2,3,4,5},只允许缺省二维数组的个数,因为可在元素列表中得出二维数组个数=2; 而Java中:可出现int[][] arr=new int[3][],因为要结合图理解,它是先分配二维数组的内存的,一维数组的地址可以为null(注意若在此时访问arr[0][0],编译通过,但运行输出:NullPointerException),可在之后动态分配,如arr[0]=new int[4],才分配给你一维数组一个地址。

因此,应对所学知识有更深理解,见图操作结果:



而且比较有趣的是在博客上发现这样一个例子:
  1. public class Test3 {  
  2.     public static void main(String[] args){  
  3.         int test[][]={{1,2,3},  
  4.                       {4,5,6},  
  5.                       {7,8,9},  
  6.                       {10,11,12},  
  7.                       {13,14,15}};  
  8.         for(int row=0;row<5;row++){  
  9.             for(int col=0;col<3;col++){  
  10.                 System.out.print(test[row][col]+"\t");  
  11.             }  
  12.             System.out.println();  
  13.         }  
  14.         System.out.println("-------------------");  
  15.         test[4]=test[3];  
  16.         test[3]=test[2];  
  17.         test[2]=test[1];  
  18.         test[1]=test[0];  
  19.         for(int col=0;col<3;col++){  
  20.             test[0][col]=0;  
  21.         }  
  22.         for(int row=0;row<5;row++){  
  23.             for(int col=0;col<3;col++){  
  24.                 System.out.print(test[row][col]+"\t");  
  25.             }  
  26.             System.out.println();  
  27.         }  
  28.     }  
  29. }  

这在Java中编译通过且完美运行,结果:


其中我觉得需要好好理解的是:这个test[1]不像C++中是一个地址值,而更像是一个指针,能被赋予新的地址值。若放到C++中,这是“修改地址”,不能通过编译。
在这里,test[1]指向了test[0]的数据内存块,所以在test[0]数据更改时,test[1]的元素输出也随之更改。而test[2]指向的是test[1]原本指向的内存块,test[1]转移了指向,但其原本指向的内存块数据并未变,所以test[2]的元素输出不变。

但是我觉得很奇怪也很新鲜的一点就是,其实从内存分配图上来说:

其实也能感觉到二维数组的内存和一维数组的内存是分开分配的,并由指针连接。
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值