2

私はC ++の初心者です。私は Java でのプログラミングに慣れています。この特定の問題は、配列を処理するときに C++ が Java のように動作しないため、大きな問題を引き起こしています。C++ では、配列は単なるポインターです。

しかし、なぜこのコードは:

#include <iostream>
#define SIZE 3
using namespace std;

void printArray(int*, int);
int * getArray();
int ctr = 0;

int main() {
  int * array = getArray();

  cout << endl << "Verifying 2" << endl;
  for (ctr = 0; ctr < SIZE; ctr++)
    cout << array[ctr] << endl;

  printArray(array, SIZE);
  return 0;
}

int * getArray() {
  int a[] = {1, 2, 3};
  cout << endl << "Verifying 1" << endl;
  for (ctr = 0; ctr < SIZE; ctr++)
    cout << a[ctr] << endl;
  return a;
}

void printArray(int array[], int sizer) {
  cout << endl << "Verifying 3" << endl;
  int ctr = 0;
  for (ctr = 0; ctr < sizer; ctr++) {
    cout << array[ctr] << endl;
  }
}

検証 2 と検証 3 の任意の値を出力します。おそらく、これは、配列が実際にポインターとして処理される方法と関係があります。

4

3 に答える 3

9

問題は、ローカル配列を返すことができないことです:

int a[] = {1, 2, 3};
...
return a;

無効です。a返す前に動的メモリにコピーする必要があります。現在、は自動aストレージに割り当てられているため、関数が戻るとすぐに配列のメモリが再利用され、返された値が無効になります。配列を含むすべてのオブジェクトが動的ストレージに割り当てられるため、Java には同じ問題はありません。

さらに良いことに、配列を置き換えるように設計された C++ クラスを優先して、配列の使用を避ける必要があります。この場合、 a を使用するstd::vector<int>方が適切です。

于 2012-10-05T02:42:48.653 に答える
6

配列がスタックに割り当てられているためです。Java から C++ に移行する場合、オブジェクトの有効期間について十分に注意する必要があります。Java では、すべてがヒープに割り当てられ、参照がなくなるとガベージ コレクションが行われます。

ただし、ここでは、スタックに割り当てられた配列 a を定義します。これは、関数 getArray を終了すると破棄されます。これは、ベクトルが単純な配列よりも好まれる (多くの) 理由の 1 つです。ベクトルは割り当てと割り当て解除を処理します。

#include <vector>

std::vector<int> getArray() 
{
    std::vector<int> a = {1, 2, 3};
    return a;
}
于 2012-10-05T02:48:59.293 に答える
1

メモリには、変数が移動できる場所が 2 つあります。スタックとヒープです。スタックには、メソッドで作成されたローカル変数が含まれています。ヒープは、静的変数など、他の条件で他の変数を保持します。

作成するaと、GetArray()それはスタックに格納されたローカル変数であり、aその場所へのポインターでした。メソッドがポインターを返すと、スタックのそのレイヤーが解放されました (ポインターが指していた実際の値を含む)。

代わりに、配列を動的に割り当てる必要があります。その後、値はヒープにあり、関数が戻ったときにクリアされず、aそこを指します。

int * GetArray() {
  int* a = new int[3];
  a[0] = 1;
  a[1] = 2;
  a[2] = 3;
  cout << endl << "Verifying 1" << endl;
  for (int ctr = 0; ctr < 3; ctr++)
    cout << a[ctr] << endl;
  return a;
}

これで、関数との間でこれらの int のアドレスを渡していますが、値はすべて、プログラムの最後まで、または (できれば) それらが解放されるまでヒープに置かれていますdelete

于 2012-10-05T02:55:28.200 に答える