2011-10-03 4 views
1

기본적으로 n-queen 문제를 해결하는 기본 프로그램을 작성해야하지만 입력 한 번호가 11보다 큰 경우 세그먼트 화 오류가 발생합니다. .재귀 n-queen 프로그램에서 C++ 세그먼트 화 오류 오류 발생

온라인에서 읽은이 오류는 일반적으로 메모리를 처리 할 때 결함이있는 논리로 인해 발생하지만 일반적으로 잘못된 것을 파악하지 못하는 것 같습니다.

void generateBoard(int board[],int column,int length,int count) 
{ 
    if(column == 0 && board[0]<length) //prevents outputting the results infinitely 
    { 
     ++board[0]; 
     generateBoard(board, ++column, length, count); 
    } 
    else 
    { 
     bool lineNotFound = true; 
     int row = board[column]; 
     while(lineNotFound && row < length) 
     { 
      ++row; //temporary value for a column value candidate 
      lineNotFound = false; 
      for(int i = 0; i < column && !lineNotFound; ++i) 
      { 
       if(board[i] == row || (board[i]+column-i) == row || (board[i]-column+i) == row) // check diagonal and horizontal 
       { 
        lineNotFound = true; 
       } 
       else 
       { 
        board[column] = row; 
       } 
      } 
     } 
     if(column == length-1 && !lineNotFound) // at last column and valid board 
     { 
      output(board,length,++count); 
      generateBoard(board,column,length,count); 
     } 
     else if(!lineNotFound) // not at last column, but valid position found 
     { 
      generateBoard(board,++column,length,count); 
     } 
     else if(column != 0) //no valid columns, go back a step 
     { 
      board[column] = 0; 
      generateBoard(board,--column,length,count); 
     } 
    } 
} 

는 그 코드의 큰 덩어리입니다 실현,하지만 난 그게 문제의 아이디어를 얻을 모두를 게시하는 데 필요한 것 같아요.

아이디어가 있으십니까? : s

저는 프로그래밍 C++을 처음 사용하기 때문에 디버깅을 시작할 위치를 모르겠습니다.

+0

세분화 오류가 발생하는 함수를 호출하는 데 사용하는 매개 변수 값을 쓸 수 있습니까? –

+0

"프로그래밍 C++을 처음 사용하기 때문에 디버깅을 시작할 위치를 알 수 없습니다." 디버거에서 프로그램을 실행하여 시작하십시오! 그것으로 당신은 어떤 라인이 폭발하는지 알 수 있습니다. 그것은 무엇이 잘못되었는지 알아내는 데 필요한 정보를 제공해야합니다. –

+0

int board [boardSize]; 채우기 (board, board + boardSize, 0); generateBoard (board, 0, boardSize, 0); 그래서이 경우 generateBoard (board, 0, 11,0); –

답변

6

처음부터 디버깅을 시작한 다음 세그멘테이션 오류가 발생할 때까지 실행하십시오. 오류가 발생하면 스택을 살펴보십시오. 나는 당신이 재귀와 함께 당신의 스택을 초과하고 있다고 생각할 것입니다 - 그것은 재귀 프로그램의 주된 문제입니다.

스택을 확대하면 입력 11에서는 발생하지 않지만 다른 숫자로는 오류가 발생하지만 재귀 프로그램은 입력이 충분히 큰 스택 문제에서 항상 중단됩니다.

그런데 - 재귀가 경계되어 있는지 확인하십시오. 즉, 어떤 시점에서 함수 자체를 더 이상 호출하지 않고 종료해야합니다. IMHO, 처음에는 재귀가 끝나는 조건을 명확하게 볼 수 있고 무한 재귀를 디버그하는 것이 더 쉬울 것이기 때문에 (처음에는 스타일과 편의성의 문제가 있지만) seg 결함을 일으키는 것이 더 낫다. 스택 고갈로 인해). 귀하의 경우에는 재귀가 어떻게 끝나는 지 즉시 알 수 없으며 일부 입력에 대해서는 그렇지 않습니다.

일부 시스템에서 당신은 "스택 오버플로"오류다면 설명은, 다른 사람에 당신은 같은 일에 대해 "분할 오류"를 얻을 것입니다. 나는 당신이 "다른 사람들"중 한 사람인 것 같아요.

것을 표시하려면

은, 난 그냥 컴파일이 코드를 실행 : 내 GCC/Ububtu 기계에

int foo(long a) 
{ 
    return foo(a-1); 
} 


int main() 
{ 
    return foo(9999999999L); 
} 

합니다. 이 프로그램은 "세그멘테이션 오류"으로 끝나는 무한 재귀가 있습니다.

반복적 인 알고리즘을 반복적으로 변환 할 수 있습니다. 새로운 변수로 재귀 적으로 함수를 호출하는 대신 STL std::stack을 사용하여 푸시 앤 팝하고 루프로 실행하십시오. 여기 세부 정보 : http://www.cplusplus.com/reference/stl/stack/

+0

보드 크기 8의 VC++에서 스택 오버플로를 얻을 수있었습니다 :-) – xanatos

+0

아마 스택 대신 힙을 사용해야합니까? – mydogisbox

+1

@mydogisbox : 힙 사용?! 호출 스택 대신 힙을 호출합니까? 그 소리는 ... 흥미 롭습니다 : P –

관련 문제