2010-01-27 6 views
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이 프로그램을 호출 할 것 : 나는 GDB를 사용하여 실행하고 역 추적을 한 적이 <

infile.in ./program. 항상 "문자열 입력;"을 가리 킵니다.

어떻게하면이 segfault를 해결할 수 있습니까? 감사합니다

+3

런타임 배열 크기 조정은 표준 C++과 호환되지 않습니다. gcc가 허용하는 이유는 C99와 호환되기 때문입니다. – doron

+0

루프에서 사용되는 변수를 포함하여 변수에 더 나은 이름을 사용해야합니다. 'i'는 하나의 루프가있을 때 훌륭한 이름이지만, 3 개의 중첩 된 루프가있을 때 레벨, 행, 열 ...이라는 적절한 이름을 부여하면 더 좋을 것입니다. 또한 왜 그런지 이해가되지 않습니다. 문자열의 내용을 덤프하고지도에 복사하는 동적 문자 배열을 만드는 ... 문자열에서 직접 복사하지 않는 이유는 무엇입니까? –

답변

7

map은 스택에 할당 된 VLA이므로 스택 오버플로가 발생하는 것이 문제라고 생각합니다. gdb는 input의 생성을 가리 킵니다. 왜냐하면 그것이 오버플로 된 스택에서 생성되기 때문입니다.

+0

예, 100 * 100 * 100은 대부분의 시스템에서 스택 크기 인 메가 바이트입니다. 대신 malloc()을 사용하십시오. –

+0

감사합니다. 이것은 매우 도움이되었습니다. – zebraman

+3

그들은이 웹 사이트 뒤에 오류를 짓는 것이 재밌다. –

2

백 트레이스가 string input;을 가리키는 이유는 확실하지 않지만 rowmap에 복사 할 때 확실하지 않습니다. mapsize가 행의 크기보다 큰 경우 잘 세분화 될 수 있습니다. 이것은 더 큰 mapize에 더 일반적 일 것입니다.

"잘못된"코어 덤프의 원인이 될 수있는 스택의 리턴 주소를 스톰핑하고있을 수도 있습니다.