1

getlineを使用してinfileから行を文字列に読み取り、文字列を文字列の最初のm個の非空白文字を含むc文字列に変換してから、c文字列を単一のchar配列に連結するプログラムを作成しています。

サンプルファイルは次のようになります。

5    //number of rows and columns in a grid
2    //number of grids
XXXXX
XXXXX
XXXXX
XXXXX
XXXXX

XXXXX
XXXXX
XXXXX
XXXXX
XXXXX

したがって、2x5x5文字のchar配列になります。 問題は、上記のような小さなテストケースではコードが正常に機能することですが、大きなグリッド(100x100x100など)で試してみるとセグメンテーション違反が発生します。

#include <iostream>
#include <string>
using namespace std;
int main(){
  int mapsize,levels;
  cin>>mapsize;
  cin>>levels;
  char map[mapsize*mapsize*levels];
  string input;
  for (int i=0;i<levels;i++){
    for (int j=0;j<mapsize;j++){
      getline(cin,input);
      char *row;
      row=new char[input.size()+1];
      strcpy(row, input.c_str());
      for (int k=0;k<mapsize;k++){
        map[i*mapsize*mapsize+j*mapsize+k]=row[k];
      }
      delete [] row;
    }
  }
return 0;
}

このプログラムをinfileで呼び出します:./ program <infile.in

gdbを使用して実行し、バックトレースを実行しました。常に「文字列入力」という行を指します。

このセグメンテーション違反を解決する方法はありますか?ありがとう

4

2 に答える 2

7

mapスタックに割り当てられたVLAなので、スタックオーバーフローが発生することが問題だと思います。gdb は、inputこのオーバーフローしたスタックで構築される最初のものであるため、 の構築を指します。

于 2010-01-27T18:53:00.057 に答える
2

バックトレースが を指している理由はわかりませんstring input;が、にコピーrowしているときmap。mapsize が行のサイズよりも大きい場合、セグ フォールトが発生する可能性があります。これは、マップサイズが大きいほど一般的です。

また、「間違った」コアダンプを引き起こしている可能性のあるスタック上のリターン アドレスを踏みにじっている可能性もあります。

于 2010-01-27T19:00:14.293 に答える