我有兩個相同程序的例子。這個程序有一個函數,它創建一個數組並返回指向數組的指針。C和JAVA程序之間的區別
第一節目(在C):
#include <stdio.h>
#include <stdlib.h>
#define N 5
int* GetValues()
{
int items[N] = { 1, 2, 3, 4, 5 };
return items;
}
int main(int argc, char** argv) {
int *array = GetValues();
int i;
for(i = 0; i < N; i++)
{
printf("%d\n", array[i]);
}
return (EXIT_SUCCESS);
}
第二程序(在Java中):
package tests;
public class Tests {
public static int[] foo() {
int array[] = { 1, 2, 3, 4, 5 };
return array;
}
public static void main(String[] args) {
int[] array = foo();
for(int i = 0; i < array.length; i++) {
System.out.println(array[i]);
}
}
}
Java程序的結果如下:1,2,3, 4,5
C程序的結果如下:1 -1075386156 -1218492432 1 -1216747208
爲什麼我們會得到不同的結果?我的版本如下。
在GetValues()函數內部的C程序中,將會創建並初始化items [] local array。返回instraction將返回指向數組開始的指針,但該數組將被分配到該函數的LOCAL內存中。當GetValues()函數的最後一條指令被調用時,本地內存將被銷燬。在這種情況下,我們無法預測哪些數據存儲在那裏,我們不知道將打印什麼指令(難怪,內存已被破壞並且值也是如此)。
在java程序中我們有以下情況。 JAVA中的數組是對象。 java中的對象存儲在堆中。因此,執行foo()
方法後,將創建對象array
並將其放入堆中。執行完方法後,局部變量將被清除,但我們的指針array
-object仍然在堆中(垃圾回收器會理解何時該對象必須被刪除),這就是爲什麼我們能夠正常打印它。
我對不對?我是否正確理解這些功能?如果不是,有人可以糾正我? 在此先感謝。
P.S.對不起,我的英語,我希望我解釋我的問題或多或少清楚。
你基本上是對的。這種差異的主要原因是Java沒有工具可以讓你創建一個自動存儲的參考(指針)。所以你不能簡單地在自動存儲中定義一個數組並將其作爲地址,你不得不在堆中創建數組並將其參考存儲在自動存儲中。這是一個相當嚴格的限制,但它巧妙地消除了許多可能的錯誤/暴露。 –