static 변수하나 만들고, 그 변수의 pointer와 상위 8 bit 정도 비교하시면 될 것입니다.
그렇게 되면, stack인지 아닌지정도는 구별할 수 있으며,
BSS 와 Heap은 main 시작하자 마자 sbrk 명령으로 현재 할당받은 data segment의 마지막 값을 구해 놓고 그것보다 작으면 BSS, 크면 Heap이라 추정할 수 있습니다.
단, 가정은
main 시작전에 Data Segment 메모리가 적당히 잡혀있지 않다.
main 이후 최초 만나는 malloc 은 메모리를 더 할당 받는다
입니다.
일반적으로,
BSS < 최초 Data Segment 최대 번지 < Heap < Stack 순입니다.
재미로 돌려 봤는데, 눈요기 하시라고 필요하신분도 있을 것 같애서 결과를 올려 봅니다.
#include <unistd.h>
#include <stdio.h>
int bss;
int main()
{
int stack;
int * heap;
void * beg;
beg = sbrk(0);
heap = (int *) malloc(4);
printf("BSS Sample: %p\n", & bss );
printf("Heap Begin : %p\n", beg );
printf("Heap Sample: %p\n", heap );
printf("Stack Sample: %p\n", & stack);
return 0;
}
Meyers의 More Effective C++
Item 27: Requiring or prohibiting heap-based objects.
변수의 위치가 힙,스택,전역인지를 판단하기는 힘들다는 문제점과 함께 피해야 한다고 하네요. 그런 구분이 필요한 설계를 피하는 것이 더 낫지 않을까 합니다만...
그럼, 이만...
bugiii님의 인용과 pynoos 님이 소개한 방법에 대한 몇 가지 첨언을 해보죠.
pynoos님의 실험처럼, 시스템마다 힙, 스택, 전역 메모리 공간의 배치 방법은 서로 다릅니다. 코드의 이식성을 심각히 위배하는 방법이죠.
물론 대부분의 시스템이 스택 메모리는 최상위 주소에서 시작하여 하위로 자라나가고, 힙과 전역 메모리는 최하위 주소에서 시작하여 자라나가지만(이것은 물론 ANSI 표준에 정해져 있는 것이 아닙니다!), AIX의 예외에도 보듯이 힙과 전역 메모리의 위치는 시스템마다 다릅니다.
게다가 sbrk라는 POSIX 함수를 호출해야 하지요. 예를 들어 WIN32라면 다른 방법을 사용해야 한다는 얘기입니다.
또한 이런 문제점 때문에, 변수가 스택에 있는지를 체크하려면
임의로 선언한 정적변수(pynoos님의 코드에 있는 'bss' 변수)와 비교하는 방법은 시스템에 따라 정확하지 않습니다.
다음과 같이 스택에 임의의 변수를 선언한 후 비교하여야 합니다.
결국 More Effective C++, Item 27에서 제시한 내용을 정리하면,
변수의 위치가 힙, 스택, 전역인지를 이식성 있게 판단하는 것은 불가능합니다.
보통 이렇게 객체가 힙에 있는 지를 체크하는 경우는 'delete this'를 해도 되는 지를 체크하기 위한 것이 대부분입니다. 즉, 이 포인터에 delete를 해도 되는 지를 판단하는데 사용하는 것이죠.
반면에 기본 제공 타입에서는 변수가 힙에 생성되었는가를 판단할 필요가 없는 것이 정상적인 프로그램입니다.
MEC++에서는 int, char와 같은 기본 타입이 아니라 사용자 정의 클래스인 경우에, 'delete this'를 해도 되는 지를 판단할 수 있는 이식성 있는 방법을 소개하고 있습니다.
operator new와 operator delete 를 오버로딩하여, operator new에서 반환한 포인터를 별도의 컨테이너(이 책에서는 std::list를 사용했습니다.)에 넣고 관리하는 방식으로 해결한다는거죠.
MEC++은 그 외에도 객체를 힙에만 생성되게 한다던가, 힙에 생성되지 못하게 하는 이식성 있는 방법을 소개하고 있습니다.
개인적으로는 MEC++에서 가장 재미있던 항목 중 하나였습니다.
변수 Scope
코드에서 변수가 어떤 위치에 만들어 져 있는지 알 수 있는 함수는 없고..
어떤 꽁수로 알아 낼 수 있을지는 모르겠지만...
프로그램을 작성하는 프로그래머 자신은 알고 있지 않습니까?
함수 밖에서 선언했다면 global
함수 안에서 선언했다면 stack
함수 안에서 선언하면서 static을 줬다면 global
malloc등으로 할당했다면... heap
프로그래머 자신은 알고 있을텐데...
님의 경우 현재 상황이 런타임중에 결정할 필요가 있나보죠?
...
Meyers 의 More Effective C++
Item 27: Requiring or prohibiting heap-based objects.
변수의 위치가 힙,스택,전역인지를 판단하기는 힘들다는 문제점과 함께 피해야 한다고 하네요. 그런 구분이 필요한 설계를 피하는 것이 더 낫지 않을까 합니다만...
그럼, 이만...
네 그래야 겠네요답변 주신분들 감사합니다.
네 그래야 겠네요
답변 주신분들 감사합니다.
프로그램에서는 어느 위치에 있는지 확인하여 action을 하는 것은 삼가
프로그램에서는 어느 위치에 있는지 확인하여 action을 하는 것은 삼가야합니다.
다만 디버깅할때는 어디에 있는지 감을 갖는 것은 좋죠.
static 변수하나 만들고, 그 변수의 pointer와 상위 8 bit 정도 비교하시면 될 것입니다.
그렇게 되면, stack인지 아닌지정도는 구별할 수 있으며,
BSS 와 Heap은 main 시작하자 마자 sbrk 명령으로 현재 할당받은 data segment의 마지막 값을 구해 놓고 그것보다 작으면 BSS, 크면 Heap이라 추정할 수 있습니다.
단, 가정은
main 시작전에 Data Segment 메모리가 적당히 잡혀있지 않다.
main 이후 최초 만나는 malloc 은 메모리를 더 할당 받는다
입니다.
일반적으로,
BSS < 최초 Data Segment 최대 번지 < Heap < Stack 순입니다.
재미로 돌려 봤는데, 눈요기 하시라고 필요하신분도 있을 것 같애서 결과를 올려 봅니다.
제가 테스트해본 결과로는
linux kernel 2.4.2 (GLIBC_2.2.3) 에서
HPUX 10.20 에서
Solaris 2.7 (x86)에서
위와 같이 나왔구요.
AIX 4.3.3 에서는
와 같이 나오는 군요. 맨 위 가정에 위배된다고 생각합니다.
아마 AIX 는 main 이전에 메모리 확보를 어느정도 해놓고, 최초 malloc 에서 그 안의 영역이 사용되나봅니다.
다시한번 강조하는 것은 어디까지나 구현에 따른 경험을 이용한 debugging에서 사용되어야지, critical path에 사용되어서는 안됩니다.
코드상 Heap Begin이라고 썼는데, 정확한 표현이 아닙니다.
---
http://coolengineer.com
제가 지금까지 본책에는.. (몇권 안됩니다;; )stack, heap
제가 지금까지 본책에는.. (몇권 안됩니다;; )
stack, heap, static .. 이렇게 메모리가 나눠진다고 보았거든요
BSS라는건.. 제가 말하는 static영역이랑 같은건가요?
제가 보는책은 너무 기초책이라서 그런건지..
인터넷에서 찾아보면 code, data, bss, stack, heap, env
이렇게 많던데.. 막상 자세한 설명은 잘 못찾겠습니다..
이정도까진 찾아봤습니다만..
code, data, env 에 관해 설명좀 부탁드립니다 ..
아니면 어디에서 이것에 관한 자료를 찾아볼수있을까요..?
Text 는 function 내용이 들어가는 곳DATA는 Readon
Text 는 function 내용이 들어가는 곳
DATA는 Readonly value 들이 들어가는 곳
BSS는 전역함수 혹은 함수내 static 변수들이 들어가는 곳 (답변이네요.. ^^)
ENV 는 프로그램 실행시 환경변수가 들어가는 곳
입니다.
이중에서 실행파일내부에는 text, data, bss 만 들어 있으며,
heap, stack은 실행중에 가변되는 잘 알려진 특성이 있고,
env 는 stack 보다 더 큰 주소에 위치합니다.
BSS는 대개 object에서 data 길이만 잡혀있습니다.
특성을 나열하자니 한도 끝도 없겠네요...
data bss stack heap 정도의 키워드를 주니 구글 선생님이 많은 사이트를 알려주는 군요
---
http://coolengineer.com
Re: ...
bugiii님의 인용과 pynoos 님이 소개한 방법에 대한 몇 가지 첨언을 해보죠.
pynoos님의 실험처럼, 시스템마다 힙, 스택, 전역 메모리 공간의 배치 방법은 서로 다릅니다. 코드의 이식성을 심각히 위배하는 방법이죠.
물론 대부분의 시스템이 스택 메모리는 최상위 주소에서 시작하여 하위로 자라나가고, 힙과 전역 메모리는 최하위 주소에서 시작하여 자라나가지만(이것은 물론 ANSI 표준에 정해져 있는 것이 아닙니다!), AIX의 예외에도 보듯이 힙과 전역 메모리의 위치는 시스템마다 다릅니다.
게다가 sbrk라는 POSIX 함수를 호출해야 하지요. 예를 들어 WIN32라면 다른 방법을 사용해야 한다는 얘기입니다.
또한 이런 문제점 때문에, 변수가 스택에 있는지를 체크하려면
임의로 선언한 정적변수(pynoos님의 코드에 있는 'bss' 변수)와 비교하는 방법은 시스템에 따라 정확하지 않습니다.
다음과 같이 스택에 임의의 변수를 선언한 후 비교하여야 합니다.
결국 More Effective C++, Item 27에서 제시한 내용을 정리하면,
변수의 위치가 힙, 스택, 전역인지를 이식성 있게 판단하는 것은 불가능합니다.
보통 이렇게 객체가 힙에 있는 지를 체크하는 경우는 'delete this'를 해도 되는 지를 체크하기 위한 것이 대부분입니다. 즉, 이 포인터에 delete를 해도 되는 지를 판단하는데 사용하는 것이죠.
반면에 기본 제공 타입에서는 변수가 힙에 생성되었는가를 판단할 필요가 없는 것이 정상적인 프로그램입니다.
MEC++에서는 int, char와 같은 기본 타입이 아니라 사용자 정의 클래스인 경우에, 'delete this'를 해도 되는 지를 판단할 수 있는 이식성 있는 방법을 소개하고 있습니다.
operator new와 operator delete 를 오버로딩하여, operator new에서 반환한 포인터를 별도의 컨테이너(이 책에서는 std::list를 사용했습니다.)에 넣고 관리하는 방식으로 해결한다는거죠.
MEC++은 그 외에도 객체를 힙에만 생성되게 한다던가, 힙에 생성되지 못하게 하는 이식성 있는 방법을 소개하고 있습니다.
개인적으로는 MEC++에서 가장 재미있던 항목 중 하나였습니다.
pynoos님 감사합니다.. :D 검색을 좀 더 해볼걸 그랬네요;;
pynoos님 감사합니다.. :D
검색을 좀 더 해볼걸 그랬네요;;
이제 자세한 내용은 구글선생님께 여쭈어 보겠습니당..ㅎㅎ 8)
제가 제안한 상위 8 bit 비교방법에 대한 반증은 Solaris의 예에
제가 제안한 상위 8 bit 비교방법에 대한 반증은 Solaris의 예에서 바로 나왔군요.
stack 에 있는지에 조사하는 방법에 대해 cedar 님의 방법에 동의 합니다. :lol:
재미로 그 함 수를 좀 더 줄이자면..
그리고 AIX의 예가 heap과 전역 메모리의 순서가 다른 OS와 다르다고 생각되지는 않습니다. 좀더 테스트 해봐야겠군요.
귀찮아서.. 나중에 시간날 때... -.- :wink:
단순 프로그래밍에서 디버깅을 심도 있게 해야할 때 만났던, 좋은 주제였습니다.
---
http://coolengineer.com
요즘 이 문제때문에
요즘 이 문제때문에 아주 골치를 앓고 있는데...
제가 이제까지 모은 정보를 좀 추가를 하면...
_참고
linux - linux는 stack/heap을 공유해서 사용함으로 heap begin과 stack begin을 중간으로 잘라서 사용하시면 그럭저럭 잘 맞습니다.
HP-UX B.11.11 9000/800
SunOS 5.9 sun4u
AIX 1 00572BED4C00
Windows_NT x86 - 일반 데스크탑
위 추정치는 아주 근사치이니 그냥 사용 하셔도 무방할겁니다.
윈도우즈 노트북(XP)
heap1
stack
heap2
노트북은 위와 같은 구조로 아주 우끼게 되어 있습니다.
참고 하시길...
혹시나 여기에 정보 추가 해주실분... 추가 해도 무방합니다.
각 OS의 stack의 끝을 알고 싶습니다.
정보를 좀 더 찾아야 할듯...
<어떠한 역경에도 굴하지 않는 '하양 지훈'>
#include <com.h> <beer.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);
#include <com.h> <C2H5OH.h> <woman.h>
do { if (com) hacking(); if (money) drinking(); if (women) loving(); } while (1);
노트북은.. 참
노트북은.. 참 새롭군요!!
-----------------
한글을 사랑합니다.
-----------------
한글을 사랑합니다.
첨언을 하자면,.
노트북이 아니라 XP가 웃기게 되어 있는거겠죠.. ;)
http://nicesj.com
https://nicesj.com
https://blog.nicesj.com
댓글 달기