Ошибка сегментации в зависимости от длины строки? - PullRequest
1 голос
/ 27 января 2010

Я пишу программу, которая будет читать строки из infile, используя getline, в строки, преобразовывать строки в c-строки, содержащие первые m непробельных символов строки, а затем объединять c-строки в один массив символов.

Пример файла может выглядеть примерно так:

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

XXXXX
XXXXX
XXXXX
XXXXX
XXXXX

Таким образом, я бы получил массив символов размером 2x5x5. Теперь проблема в том, что мой код отлично работает на меньших тестовых примерах, как показано выше, но сегментация дает сбой, когда я пробую ее на больших сетках (т.е. 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;
}

Я бы назвал эту программу инфилом: ./program

Я запустил его с помощью GDB и сделал backtrace. Он всегда указывает на строку «ввод строки;»

Любые идеи, как я могу решить этот segfault? Спасибо

Ответы [ 2 ]

7 голосов
/ 27 января 2010

map - это VLA, размещенный в стеке, поэтому я предполагаю, что ваша проблема заключается в переполнении стека. GDB указывает на конструкцию input, потому что это первое, что создается на этом переполненном стеке.

2 голосов
/ 27 января 2010

Я не уверен, почему обратная трассировка указывает на string input;, но когда вы копируете row в map. если размер карты больше, чем размер строки, вы можете в конечном итоге привести к сбою. Это будет более распространенным для больших карт.

Вы также можете топать адреса возврата в стеке, которые могут вызывать «неправильный» дамп ядра.

...