프로그램의 C / C ++ 최대 스택 크기


115

100 X 100 어레이에서 DFS를 수행하고 싶습니다. (배열의 요소는 그래프 노드를 나타냄) 따라서 최악의 경우를 가정하면 재귀 함수 호출의 깊이는 각 호출이 최대 20 바이트를 차지할 때 최대 10000까지 올라갈 수 있습니다. 그렇다면 스택 오버플로의 가능성이 있다는 것이 가능한 수단입니까?

C / C ++에서 스택의 최대 크기는 얼마입니까?


1) Windows의 cygwin
2) Unix 에 대해 gcc를 지정하십시오.

일반적인 제한은 무엇입니까?


11
재귀없이 깊이 우선 검색을 구현할 수 있다는 것을 알고 있습니까?
Sebastian

4
아니요, 모르겠습니다. 설명해주세요.
avd

1
내 대답에 재귀없는 DFS의 작은 예를 만들었습니다
Andreas Brinck 2009

56
플러스 실제 스택 오버 플로우에 대한 질문에 대한 한
샘 왓킨스

3
@SamWatkins 예, Stack Overflow라는 이름의 가장 큰 문제 중 하나는 Google에서 "스택 오버플로"를 찾아이 웹 사이트에서 끝날 수 있지만 스택 오버플로에 대한 질문에서 반드시 / 적은 것은 아니라는 것입니다 ...
lalilulelost

답변:


106

Visual Studio에서 기본 스택 크기는 1MB라고 생각하므로 재귀 깊이가 10,000이면 각 스택 프레임이 최대 ~ 100 바이트가 될 수 있으며 DFS 알고리즘에 충분합니다.

Visual Studio를 포함한 대부분의 컴파일러를 사용하여 스택 크기를 지정할 수 있습니다. 일부 (모두?) Linux 버전에서 스택 크기는 실행 파일의 일부가 아니라 OS의 환경 변수입니다. 그런 다음으로 스택 크기를 확인하고 ulimit -s예를 들어를 사용하여 새 값으로 설정할 수 ulimit -s 16384있습니다.

다음 은 gcc의 기본 스택 크기에 대한 링크 입니다.

재귀없는 DFS :

std::stack<Node> dfs;
dfs.push(start);
do {
    Node top = dfs.top();
    if (top is what we are looking for) {
       break;
    }
    dfs.pop();
    for (outgoing nodes from top) {
        dfs.push(outgoing node);
    }
} while (!dfs.empty())

12
참고로 BFS는 스택 대신 FIFO를 사용한다는 점을 제외하면 동일합니다.
Steve Jessop

예, 또는 STL-lingo에서는 pop_front / push_back과 함께 std :: deque를 사용합니다
Andreas Brinck 2009

스택 결과가있는 DFS는 재귀 버전과 다릅니다. 어떤 경우에는 문제가 있지만, 다른 사람 (. 예에 대한 위상 종류의) 당신은 잘못된 결과를 얻을하지 않습니다
spin_eight

예, VS의 기본 제한은 실제로 1MB입니다. 자세한 정보와 다른 값을 설정하는 방법은 Microsoft 설명서에서 찾을 수 있습니다. msdn.microsoft.com/en-us/library/tdkhxaks(v=vs.140).aspx
FrankS101 2016 년

재귀보다는 이러한 알고리즘에 대해 명시적인 스택 데이터 구조를 사용하는 것을 선호합니다. 따라서 1. 시스템 스택의 크기에 의존하지 않습니다. 2. 다른 데이터 구조를 사용하도록 알고리즘을 변경할 수 있습니다 (예 : 큐 또는 우선 순위 큐). 모든 코드.
Sam Watkins


17

플랫폼 의존적, 도구 체인 의존적, ulimit 의존적, 매개 변수 의존적 .... 그것은 전혀 지정되지 않았으며 영향을 줄 수있는 많은 정적 및 동적 속성이 있습니다.


4
"일반적인 제한"은 없습니다. Windows에서는 기본 VC ++ 링커 옵션 및 기본 CreateThread 동작 (일반적으로 스레드 당 약 1MiB)이 있습니다. 무제한 사용자가있는 Linux에서는 일반적으로 제한이 없다고 생각합니다 (스택이 거의 전체 주소 공간을 차지하기 위해 아래로 커질 수 있음). 기본적으로 물어봐야한다면 스택을 사용해서는 안됩니다.
DrPizza 2009

1
임베디드 시스템에서는 4k 이하일 수 있습니다. 이 경우 스택을 사용하는 것이 합리적 일 때도 물어봐야합니다. 대답은 일반적으로 Gallic shrug입니다.
Steve Jessop

1
아 맞다. 커널 모드에서도 마찬가지다.
DrPizza

6

예, 스택 오버플로의 가능성이 있습니다. C 및 C ++ 표준은 스택 깊이와 같은 것을 지시하지 않으며 일반적으로 환경 문제입니다.

대부분의 적절한 개발 환경 및 / 또는 운영 체제를 사용하면 링크 또는로드 시간에 프로세스의 스택 크기를 조정할 수 있습니다.

보다 구체적인 지원을 위해 사용중인 OS 및 개발 환경을 지정해야합니다.

예를 들어 Ubuntu Karmic Koala에서 gcc의 기본값은 2M 예약 및 4K 커밋이지만 프로그램을 연결할 때 변경할 수 있습니다. 이를 수행하려면의 --stack옵션을 사용하십시오 ld.


2
@lex : 일반적인 제한이 없습니다. 많은 매개 변수에 따라 다릅니다.
Michael Foukarakis 2009

@paxdiablo : WHat은 예약 및 커밋의 의미입니까?
avd

2
Reserved는 할당 할 주소 공간의 양이고, commit은 백업 스토리지를 첨부 할 양입니다. 즉, 주소 공간을 예약한다고해서 필요할 때 메모리가있는 것은 아닙니다. 4K 스택 이상을 사용하지 않는다면 다른 1.6M에 대한 실제 메모리를 낭비하지 않습니다. 스택이 충분하다는 것을 보장하려면 예약 및 커밋이 동일해야합니다.
paxdiablo

2
@paxdiablo 2M-4k는 1.6M이 아닙니다. 그냥 말해. (내가 귀하의 의견을 읽은 처음 세 번 헷갈
griffin

2
@griffin, 3 년 이상 만에 처음으로 잡은 사람에 대한 찬사입니다. 나는 물론 "그것의 나머지"를 의미했습니다. 다른 가능한 실수 를하지 않도록 실제 수치를 피할 것입니다. :-)
paxdiablo 2013-08-28

5

방금 직장에서 스택이 부족했고 데이터베이스 였고 일부 스레드를 실행 중이었습니다. 기본적으로 이전 개발자가 스택에 큰 배열을 던졌고 스택은 어쨌든 낮았습니다. 이 소프트웨어는 Microsoft Visual Studio 2015를 사용하여 컴파일되었습니다.

쓰레드는 스택이 부족했지만 조용히 실패하고 계속해서 스택에있는 데이터의 내용에 액세스 할 때만 스택 오버플로가 발생했습니다.

내가 줄 수있는 가장 좋은 조언은 스택에서 배열을 선언하지 않는 것입니다. 특히 복잡한 애플리케이션, 특히 스레드에서 대신 힙을 사용하십시오. 그것이 거기에있는 것입니다;)

또한 스택을 선언 할 때 즉시 실패하지 않고 액세스 할 때만 실패 할 수 있음을 명심하십시오. 내 생각 엔 컴파일러가 "낙관적으로"윈도우 아래에서 스택을 선언한다는 것입니다. 즉, 스택이 선언되었고 스택을 사용할 때까지 충분히 크기가 조정되었다고 가정하고 스택이 거기에 없다는 것을 알게됩니다.

운영 체제마다 스택 선언 정책이 다를 수 있습니다. 이 정책이 무엇인지 아는 경우 의견을 남겨주세요.


3

직사각형 배열에서 깊이 우선 검색을 수행하는 것이 무엇을 의미하는지 잘 모르겠지만 수행중인 작업을 알고 있다고 가정합니다.

스택 한계가 문제라면 재귀 솔루션을 힙에서 할당 된 스택에 중간 값을 푸시하는 반복 솔루션으로 변환 할 수 있어야합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.