1

ファイル (myfile.in) から 2D 配列を読み込もうとしています。行と列が与えられます。

myfile>>n>>m; //rows and cols
for(int i = 0; i < n; i++) {
    for(int j =0; j < m; j++) {
    myfile>>tab[i][j];
    cout<<tab[i][j]<<" ";
    }
    cout<<endl;
}

そして、画面上の出力は本来あるべきものです(ファイルにあるように):

1 0 0 0 1 0 1
0 1 1 1 1 0 0
0 0 1 0 1 1 0
0 1 0 0 1 0 0
0 1 0 0 0 1 1
1 1 1 1 0 0 0
0 1 0 0 0 1 1

その後、配列を個別に印刷しようとしました。

for(int i = 0; i < n; i++) {
    for(int j =0; j < m; j++) {
    cout<<tab[i][j]<<" ";
    }
    cout<<endl;
}

出力は次のとおりです。

0 1 0 0 0 1 1
0 1 0 0 0 1 1
0 1 0 0 0 1 1
0 1 0 0 0 1 1
0 1 0 0 0 1 1
0 1 0 0 0 1 1
0 1 0 0 0 1 1

実際には最後の行が表示されていますが、なぜですか?

4

2 に答える 2

2

あなたのコメントによると、実際には tab を に初期化していますtab[0][0]。コンパイラがそれを許可する理由はわかりませんが、重要なことは、配列の境界の外に書き込んでおり、未定義の動作を引き起こしていることです。

n と m を読み取った、配列を動的に割り当ててみてください。

int n, m;
file >> n >> m;

int **tab = new int* [n];
for(size_t i = 0; i < n; ++i)
{
  tab[i] = new int[m];
}

このようにして、常に必要なだけのメモリを割り当てることができます。

また、完了したら配列を削除することを忘れないでください。

for(size_t i = 0; i < n; ++i) delete[] tab[i];
delete[] tab;

ご覧のとおり、この方法は不要な複雑さを少し追加する傾向があります。エレガントな代替手段は、次のようなコンテナを使用することstd::vector<std::vector<int>>です:

using namespace std;

vector<vector<int>> tab;

  for(int i = 0; i < n; ++i) {
    vector<int> current_row;
    for(int j = 0; j < m; ++j) {
      int buff;
      file >> buff;
      current_row.push_back(buff);
    }

    tab.push_back(current_row);
  }
于 2013-04-06T10:41:47.703 に答える
1
int n=0, m=0; int tab[n][m];

これは、次の 2 つの理由から正当な C++ ではありません。

  1. 配列の次元は定数式でなければなりません。nそうでmはありません。

  2. サイズが 0 の配列を作成しています。

    定数式 (5.19) が存在する場合、[...] その値は 0 より大きくなければなりません。

これらの両方を受け入れる拡張機能があるため、コンパイラはそれを受け入れています。それにもかかわらず、配列のサイズは 0 であるため、要素はありません。書き込もうとするものはすべて、配列の範囲外になります。

読み取りmyfile>>n>>m;によって配列のサイズが自動的に変更されることはありません。すでにサイズ 0 として宣言しています。何も変更しません。

std::vector代わりに、実行時にサイズを変更できるなどの標準ライブラリ コンテナーを使用する方がはるかに優れています。検討:

myfile >> n >> m;
std::vector<std::vector<int>> tab(n, std::vector<int>(m));

tabその後、上記とまったく同じ方法でこのオブジェクトを使用できます。

于 2013-04-06T10:42:29.163 に答える