스택 크기를 구하는 소스가 제대로 되었나요?
자료구조를 보다가 재귀호출에서 스택의 오버플로를 언급하길래 어느 정도가 되면 오버플로가 일어나는지 궁금했습니다. 찾아보니 VS에서는 기본 1MB라고 하더군요.
http://msdn2.microsoft.com/ko-kr/library/8cxs58a6(VS.80).aspx
그래서 직접 구해보려고 아래의 소스를 실행해봤습니다. 스택 크기는 depth와 totalSize의 크기, 그리고 복귀 주소로 구했는데 오버플로우는 130MB정도에서 일어났습니다.(볼랜드 C++ 5.5에서는 504MB) 무엇을 잘못 이해하고 있는지 고민하다 답이 안나와서 이렇게 질문을 올립니다.
#include "stdio.h"
void StackOverflow(int depth, int totalSize)
{
totalSize += (sizeof(int) * 2) + sizeof(void*);
printf("depth : %d\ttotal size : %d byte\t%d MB\n", depth, totalSize, totalSize/1024);
StackOverflow(depth+1, totalSize);
}
int main(int argc, char * argv[])
{
StackOverflow(0, 0);
return 0;
}
제가 참고했던 글들입니다.
스택 크기 구하는 소스 : http://support.microsoft.com/kb/315937
이에 대한 KLDP 질문 : http://kldp.org/node/691
힙과 스택 : http://kldp.org/node/199
소스를 보면 스택 프레임 크기를 인위적으로
계산을 하는데, 컴파일러가 어떻게 컴파일할지 알 수가 없기 때문에, 그렇게 하면 안될듯 싶습니다.
그리고 printf문에서 MB가 아니라 KB인데 오타가 있네요.
아래 소스는 스택 프레임 크기에 대해 아무런 가정을 하지 않는 소스입니다.
아아아...
답변 감사합니다.(주소의 차이로 스택 크기를 계산하는 것에 감동받았습니다. ^^)
byte, KB, MB... 왜 저리 큰 값이 나오나 고민했는데 실수했었네요.
컴파일러마다 계산을 다르게 한다는 것이 이해가 안되네요. sizeof의 값이 컴파일러 마다 다르다는 뜻은 아닐텐데 어떤 점에서 계산값이 다른지 궁금하네요.
그리고 argc가 지역변수로 가장 최초에 스택에 들어가기 때문에 top으로 잡은 것으로 이해하면 될까요?
(아.. 변수와 메모리 상관관계에 대해 아직 이해가 안되는 것 같네요.)
하나를 알면 열이 궁금해요.. 털썩... OTL
대부분의 시스템에서
대부분의 시스템에서 argc가 스택의 첫부분에 들어갈 것 같은데 가장 최초는 아닐 지 싶습니다.
스택이 Page 크기로 정렬되어있다면 top을 정렬시키면 정확한 값이 나오겠지요.
만약 Page 크기가 4KB 라면
unsigned long top_align = ( ( (unsigned long) top + (4096-1) ) / 4096) * 4096;
이런 식으로 구할 수 있습니다.
P.S. 댓글을 이상한 곳에 달았군요.
댓글 달기