2012-12-12 3 views
1

C++에서 문제가 발생하지만 스택 오버플로 예외가 발생하며 그 이유를 알 수 없습니다. main 메소드는 problem28()을 호출하지만, 첫 번째 라인은 내 출력에 "check"를 출력해야하는데, 이것은 일어나지 않습니다. gridsize를 501 이하로 정의하면 잘 실행되지만 그 이상은 아무것도 아니며 스택 오버플로 예외가 발생합니다. 메서드 호출에서 스택 오버플로 예외가 throw되었습니다.

어떤 도움

주시면 감사하겠습니다.

#define right 0 
#define down 1 
#define left 2 
#define up 3 
#define gridsize 1001 

int* next(int row, int col, int dir) { 
    int* newPos = new int[2]; 
    newPos[0] = row; 
    newPos[1] = col; 
    switch(dir) { 
    case right: 
     newPos[1] += 1; 
     break; 
    case down: 
     newPos[0] += 1; 
     break; 
    case left: 
     newPos[1] -= 1; 
     break; 
    case up: 
     newPos[0] -= 1; 
     break; 
    } 
    return newPos; 
} 

int problem28() { 
    cout << "check" << endl; 
    int grid[gridsize][gridsize]; 
    for (int i = 0; i < gridsize; i++) 
     for (int j = 0; j < gridsize; j++) 
      grid[i][j] = 0; 
    int* pos = new int[2]; 
    pos[0] = pos[1] = gridsize/2; 
    int dir = right; 


    for (int i = 1; i <= 1001; i++) { 
     grid[pos[0]][pos[1]] = i; 
     pos = next(pos[0], pos[1], dir); 
     int* npos; 

     npos = next(pos[0], pos[1], (dir + 1) % 4); 
     if (grid[npos[0]][npos[1]] == 0) 
      dir = (dir + 1) % 4; 
    } 
    cout << "generated grid" << endl; 

    int total = 0; 
    for (int i = 0; i < gridsize; i++) { 
     total += grid[i][i]; 
     total += grid[i][gridsize - i - 1]; 
    } 
    total -= grid[gridsize/2][gridsize/2]; 

    return 0; 
} 

int main() { 
    problem28(); 

    system("pause"); 
    return EXIT_SUCCESS; 
} 
+0

의 #pragma 주석 감지 할 수있는 Linux의

(링커, "/ STACK : 16777216")이 당신에게 스택 –

답변

3

스택은 일반적으로 전체 메모리에 비해 상당히 제한적입니다.

int grid[gridsize][gridsize]; 

에 : 작업이 가장 가능성있는 가장 쉬운 수정 변경하는 것입니다 지금까지 problem28 때문에, 재귀 될 것 같지 않습니다 정적으로 대신 해당 배열에 대한 메모리를 할당합니다

static int grid[gridsize][gridsize]; 

이는 일반적으로 더 이상 스택에 없다는 것을 의미합니다.

또 다른 가능성은 배열 대신 std::vector을 사용하는 것입니다. 이것은 보통 로컬이 아닌 무료 저장소에서 메모리를 할당합니다. 사소한 문제는 vector (그 자체)이 2D 주소 지정을 제공하지 않기 때문에 별도로 처리해야한다는 것입니다 (예 : 이전 답변에 게시 된 array_2D 사용).

+1

'static'을 추가했습니다. 도와 주셔서 감사합니다. – excaliburHisSheath

1

나는보다 501가 잘 실행 덜하지만, 아무것도 더으로 gridsize을 정의하면 그것은 스택 오버 플로우 예외가 발생합니다.

전체 grid 배열이 스택에 있습니다. int이 32 비트 폭인 경우 int[500][500]은 ~ 1MB를 차지하며 일부 운영 체제에서는 기본 최대 스택 크기가됩니다.

스택의 크기를 늘리거나 힙에 grid을 (되도록) 할당 할 수 있습니다.

+0

@phonetagger 16 MB의 제공 :하지를 들어 전통적인 값인 '500'과 '4', 전통적인 메가 바이트 크기. – NPE

+0

@phonetagger : 이렇게하면 'int'4x4 바이트가 넓어집니다. 이것이 내가 처음에 보았던 2D int입니다. :) – NPE

+0

아 ... 네. 너 다행이야. 아니면 여자. 또는 무엇이든. – phonetagger

0

문제는 여기에있을 것 같다 :

int grid[gridsize][gridsize]; 

당신이 동적으로 2 차원 배열을 할당하려고 했습니까?

+0

동적으로 할당하는 것이 무슨 뜻인지 모르겠으니 설명해 주시겠습니까? – excaliburHisSheath

+0

@ user1898872 정적 클래스 멤버로 그리드를 생성하거나 스택 추가를 방지하려면'new()'를 사용하십시오. '동적으로'는 보통 후자를 의미하며 힙에 클래스 인스턴스를 만듭니다. –

+0

정적으로 그리드를 선언해도 작동하지만 'int * grid = new int [gridsize] [gridsize];'는 컴파일되지 않습니다. 어떻게 2D 배열을 동적으로 할당합니까? – excaliburHisSheath

0

난 당신이 충돌의 원인이되는 문제를 찾기 위해 같은 응용 프로그램 검증 같은 프로그램을 사용하는 것이 좋습니다

Application Verifier Download

그것은 당신이 당신의 소프트웨어를 디버깅하고 무슨 일이 일어나고 있는지 이해하는 방법을 학습하는 것이 중요합니다 . 디버거 (Visual Studio, Eclipse)에서 코드를 실행하고 중지 지점을 살펴보십시오. Application Verifier를 사용했다면 문제가 발생한 지점에서 멈출 것입니다. 변수를 살펴보고 이해가되는지 확인하십시오. 당신이해서는 안되는 메모리 위치에 액세스하고 있는지보십시오.

Visual Studio에서 Application Verifier를 사용하려면 설치 한 다음 C : \ Windows의 System32 폴더에서 appVerifier.exe를 찾으십시오. 그런 다음 파일을 열고 실행 파일을 가리 킵니다. 올바른 체크라고 생각하는 것을 활성화하십시오. 그런 다음 Visual Studio에서 실행하십시오.당신은 (그리고해야한다) Valgrind의를 사용하면 이러한 문제의 종류

관련 문제