2012-11-06 2 views
-2

나는이 link에서 찾을 수 있습니다 재귀 알고리즘을 구현했습니다. 3d 배열이 10x10x10 일 때 아주 잘 작동합니다. 나는 그것이 그러나 200x200x200 배열에 대해 실행되도록하기 위해 노력하고있어Visual Studio에서 'System.StackOverflowException'을 무시하도록 강제하는 방법은 무엇입니까?

은 Visual Studio에서 내가 무한 resursive (나는 내 ​​음식물은 OK입니다 확신) ussing 될 수 있다고 말한다. 그걸 처리 할 방법이 있습니까? 재귀 메서드 바로 앞에 [DebuggerNonUserCode]을 넣으려고했지만 시도하지 않았습니다.

이 얘기를 깜빡 했네요, 그것은 비주얼 스튜디오에게있어 2010 년

여기 내 프로그램에서 재귀 함수가 있습니다. 나는 Unvisited로 표시된 모든 셀에 대해 실행 중입니다.

public static int tmp_lowest_floor = 0; 
    public static int tmp_maks_size = 0; 

    static void function1(Point[, ,] array, int pos_y, int pos_z, int pos_x) // recursive function 
    { 
     Point cell = array[pos_y, pos_z, pos_x]; 

     if (cell.Visited == false && cell.IsCave) 
     { 
      cell.Visited = true; // changing to visited so we do not count anything for this cell anymore 
      tmp_maks_size++; // increasing for each cell in this cave (in this run) 

      if (tmp_lowest_floor < pos_y) { tmp_lowest_floor = pos_y; } 
      cell.FillNeighbourList(array, pos_y, pos_z, pos_x);// adds neighbours into cell's list (max 6) up, down, north, east, south, west 

      foreach (Point p in cell.neighbours) // max 6 times recursion in here (I know it sounds horrible, but once I check all the neighbours for a cell, I'll not have to check it ever again) 
      { 
       if (p != null) 
       { 
        if (p.IsCave == true && p.Visited == false) 
        { 
         function1(tablica, p.pos_y, p.pos_z, p.pos_x); 
        } 
       } 
      } 

     } 

    } 

p.s. 반복적으로 할 수 있다는 것을 알고 있지만, 숙제는 재귀를 통해 완료해야한다고 말합니다.

+0

당신은있는 StackOverflowException을 무시할 수 없습니다. 알고리즘을 비 재귀 적으로 구현하십시오. –

+1

StackOverflow는 오류가 아니라 경고입니다. 당신은 무시할 수 없습니다. – SLaks

+0

당신은 이것을 무시할 수 없을뿐만 아니라 지금까지해야합니다. – MyCodeSucks

답변

7

당신은 무시할 수 없으므로 말 그대로 쓰레기를 날 렸습니다.

당신이하는 일은 스택을 늘려서 (따라서 문제를 지연시키는 것입니다) 또는 현재 당면한 문제가 알고리즘을 실제로 구현하는 것임을 깨닫고 반복적 인 접근법을 사용하거나 꼬리를 이용하는 것입니다 호출 재귀). 여담으로

, 당신이 당신의 X 트랙, y 및 z 좌표와 아무것도를 지키는 200x200x200 배열의 모든 세포를 통해 이동하는 데 사용하는 얼마나 많은 스택을 알고 싶어? 96MB. Windows는 기본적으로 너비가 1MB 인 스택을 제공합니다.

편집 : 당신이해야하는 것은 아주 기본적인 채우기 알고리즘, 특정 문제를 해결하려면. iterative 양식은 대기열과 목록을 사용합니다. 의사 코드 :

list visited=[]; 
queue q=[]; 

q.push(startnode);   // the starting point 
while(!q.empty()) 
{ 
    // make sure we don't revisit nodes 
    if(visited.contains(node)) 
    continue; 

    visited.add(node=q.pop()); // we just visited the top 

    // do your conditions here, the cave thing? no clue what that is 
    // if it passes your filter, do any extra operations on your node here (none in your code) 

    // and push the neighbours in the queue 
    q.push_all(node.get_neighbours()); 
} 
+0

반복을 사용하는 코드를 보내 주셔서 감사합니다. 불행히도 재귀를 사용해야합니다. – Patryk

4

런타임 환경에는 유한 스택이 있습니다. 메서드를 호출 할 때마다 더 많은 데이터가 해당 스택에 추가됩니다. 메서드가 반환 될 때마다 데이터가 스택에서 제거됩니다. 메서드 내의 메서드 내에서 메서드를 계속 호출하고 해당 메서드가 반환되지 않으면 결국 스택에 공간이 부족하여 스택 오버플로가 발생합니다.

이 문제를 피하려면 메서드 내에서 메서드를 호출하는 재귀를 사용하도록 알고리즘을 수정하거나 스택이 너무 커지지 않는 작은 데이터 집합을 사용하여 콘텐츠를 작성하면됩니다.

1

당신은에 의해 크기를 스택 증가시킬 수 있습니다 : 오른쪽 프로젝트를 클릭

  • 선택 속성 -> 링커 - -> 구성 속성> '스택 예약 크기'에 대한 시스템
  • 설정 다른 값 및 '스택 커밋 크기'(바이트). 여기에서 힙 크기를 변경할 수도 있습니다.

I had similar issue with tail recursion in this question.

관련 문제