我有两个相同程序的示例。这个程序有一个函数,它创建一个数组并返回指向数组的指针。
第一个程序(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[] 本地数组。返回指令将返回指向数组开头的指针,但该数组将分配在该函数的本地内存中。当调用 GetValues() 函数的最后一条指令时,本地内存将被销毁。在这种情况下,我们无法预测那里存储了哪些数据,并且我们不知道将打印什么printf("%d\n", array[i])
指令(难怪,内存已被破坏并且值也已被破坏)。
在java程序中我们有以下情况。JAVA 中的数组是对象。java中的对象存储在堆中。因此,在执行foo()
方法之后,array
将创建对象并将其放入堆中。执行方法后局部变量会被清除,但是我们指向array
-object的指针还在堆中(垃圾收集器会明白什么时候必须删除这个对象),为什么我们能够正常打印它。
我对吗?我是否正确理解了这些功能?如果没有,有人可以纠正我吗?提前致谢。
PS对不起我的英语我希望我或多或少清楚地解释了我的问题。