同じプログラムの例が 2 つあります。このプログラムには、配列を作成し、配列へのポインターを返す関数があります。
最初のプログラム (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);
}
2 番目のプログラム (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[] ローカル配列が作成され、初期化されます。return命令は配列の先頭へのポインタを返しますが、この配列はその関数のローカルメモリに割り当てられます。GetValues() 関数の最後の命令が呼び出されると、ローカル メモリが破棄されます。この場合、そこに格納されているデータを予測することはできず、命令を出力するものもわかりprintf("%d\n", array[i])
ません (メモリが破壊され、値も破壊されているのも不思議ではありません)。
Java プログラムでは、次の状況があります。JAVA の配列はオブジェクトです。Java のオブジェクトはヒープに格納されています。したがって、foo()
メソッドを実行した後、オブジェクトarray
が作成され、ヒープに配置されます。メソッドを実行した後、ローカル変数はarray
消去されますが、 -object へのポインターはヒープ内に残っています (ガベージ コレクターは、このオブジェクトをいつ削除する必要があるかを理解します)。これが、正常に出力できる理由です。
私は正しいですか?この機能を正しく理解していますか? そうでない場合、誰かが私を修正できますか? 前もって感謝します。
PS私の英語で申し訳ありませんが、私の問題を多かれ少なかれ明確に説明したいと思います。