색다른 '나의 뇌속 구조'


dotgoon님의 글 - 미니위니

한자로 자신의 이름을 입력하면 뇌 그림 안에 뭔가 가득 채워줍니다. 물론 채워지는 건 한자라지요; 일본 사이트인데, 히라가나나 가타카나로 나오지 않는게 어디입니까 (..) 심심하면 한번 해보시는 건 어떠세요?

링크 ; http://usokomaker.com/ [일본어]

아래는 제 이름을 한자로 입력했을 때의 결과입니다.

사용자 삽입 이미지

sy의 뇌속 구조(?)


하하하, 저의 뇌 안에는 음식(食), 친구(友), 돈(金), 욕구(欲)로 차있군요. 뭐, 딱히 부정하고 싶은 생각은 없습니다; 그러고보니 저는 지금 친구와 문자로 돈에 대한 이야기를 하면서 과자를 먹고 있군요. 뭔가 많이 찔립니다, 후후.

p = (int *) malloc(0)을 한다면?

프로그래밍을 하면서 생기는 궁금증은 나를 간혹 미치게 만든다.
그 때문에, 지난 번 function과 stack, 그리고 memory에 대한 간략한 연구를 통해 친구들에게 이상한 놈 취급을 받았던 터라ㅡ아닐 수도 있다ㅡ 앞으로도 나의 궁금증에 관한 포스팅을 올려야 하는지에 대해 고민을 많이 해보았다.

그리고, 다시 궁금증을 해결하기 위해 포스팅을 시작하기로 했다.

이번에 고민하게 된 부분은, "p = (int *) malloc(0)"을 해주게 되면 어떤 결과가 나타날까,이다.
우선, man 명령어를 통해 malloc에 대한 정보를 알아보자.

Standard C Library Functions                           malloc(3C)

NAME
    malloc, calloc, free, memalign, realloc,  valloc,  alloca  -
    memory allocator

SYNOPSIS
    #include <stdlib.h>

    void *malloc(size_t size);

(이하 생략)

return type이 void인 malloc 함수는 size_t size라는 argument를 가진다. 이 size_t size 부분에는 동적으로 할당할 메모리의 크기를 지정해주면 된다. 만약 이 size_t size가 0이라면, 과연 어떻게 될까.

아주 간단하게 소스를 작성해보았다.
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
       int *p;
       p = (int *) malloc(0);
       *p = 2;
       printf("p = %x\n", p);
       printf("*p = %d\n", *p);
       free(p);
       return 0;
}

그리고, 이번에도 세 가지의 다른 시스템 상에서 컴파일 후 실행을 해보았다.
파일명은 malloc.c로 지정했으며, 세 가지 시스템의 대략적인 정보는 다음과 같다.
- Ubuntu Linux 6.06 / gcc 4.0.3 (개인PC)
- SunOS 5.8 / gcc 3.3.2 (한양대 정보통신대학 실습용 서버 a.k.a. medusa)
- Debian / gcc 3.2.3 (한양대 cancun lab의 서버 / Operating System 정보는 미확인)

그리고, 그 결과 값은 아래와 같다.
- Ubuntu Linux 6.06 / gcc 4.0.3
p : 804a008
*p : 2

- SunOS 5.8 / gcc 3.3.2
p : 209a0
*p : 2

- Debian / gcc 3.2.3
p : 9ca8008
*p : 2

위의 결과에서처럼, malloc의 size를 0으로 주었음에도, 세 시스템에서 모두 메모리 상에 정상적으로 동적 할당이 이루어졌다. 어쩌면 할당되지 않아야 할 부분이 할당되었을 수도 있을 것이고, 그게 아니라면 다른 이유가 있을 것이다.

인터넷 상에서 malloc(0)이라는 키워드를 통해 정보를 검색하다가 흥미로운 문서를 발견했다. 링크
누군가 나에게 '왜?'인지에 대해 설명해줄 것이라고 믿으면서, 조금 더 관련 자료들을 찾아봐야겠다.

궁금증, 그 끝.

장장 사흘을 넘게 나를 괴롭히던 이 궁금증.
링크1, 링크2

결국에는 내 나름대로의 결론을 얻었다. (웃음)
역시나 다른 시스템에서 나온 결론들이 옳은 것인듯.

하지만, free된 메모리를 참조했음에도 제대로 된 값이 나올 수는 없는 노릇이었을텐데. 왜 ubuntu에서는 제대로 된 값을 내보내줬는지 모르겠다. 나중에 시간이 된다면 다시 테스트를 해봐야지.

크리스마스 이브부터 기나긴 답글로 해결책을 제시해준 민영군, 트랙백까지 해주면서 다른 예시를 제시해준 남호군, 그리고 열심히 추측한 생각을 적어준 우리 티오. 모두모두 땡큐베리감사~

궁금증, 그 뒷 이야기.

우선 이 궁금증에 대한 자세한 글은 아래에 써놓기는 했지만, 그래도 링크!

그리고, 이야기를 써내려가기에 앞서, 민영신께서 도움 말씀을 전하시니,
성스런 크리스마스 이브거늘
컴퓨터랑 씨름하고 있다니 :)

일단 해당하는 문제는, machine 혹은 compiler 에 relate한 문제가 될텐데 각설하고 일반저긴 이야기를 하자면.

일반적으로 로컬 변수가 그 스코프를 벗어나게 되면 값이 사라진다는것은(=의미를 잃어버린다는것)은 로컬 스코프들이 자신이 CPU타임을 소유했을때 사용하는 공간이 같기 떄문인데(Stack).... 어지럽지?-_-;

간단히 말하자면, 실제로 같은 영역(=공간)을 쓰기 때문에 같다
라고 밖에 말해줄수가 없겠네. 메모리 아키텍쳐를 이해하려면 필수적으로 컴파일러와 링커를 이해해야 하고 그러자면 필수적으로 O/S 와 어셈블리 지식이 붙어야 하고... 갈길이 멀지?

실지로 곰곰히 생각해 보면 저러한것이 합리적이란것도 생각해 볼수 있게 되는데, 만약 계속 사용하는 공간이 달라진다면, 저러한 함수를 정말 엄청 호출해 댄다면, 쓸수 있는 공간이 동나 버리겠지. 그래서 실제로, resursive-function 같은경운 지나친 호출의 경우엔 문제가 되기도해. 스택이 동나버리거든.

이래저래 더 헷갈리게 만들어 버린것 같지만-_-; 지금은 그냥 그래서 그런가보다 할수 밖에 없단 소리. 그래도 정 궁금하면 PE Format Document 나, ELF Format Document 와 링커 그리고 어셈블리, Memory Architecture(..스펠링 맞나--) 관련 문서를 보면 좀 도움이 될꺼야~

...아하하 이브에 뭐하는 짓이람. 배고프다orz


일단 이 문제는 어느 정도, machine, system, compiler에 의존적(dependent)인 것이라, 테스트를 했던 환경에 대해 적지 않을 수 없다.

아래의 '궁금증'에 대한 글을 남겼을 때의 system은, 대략 Ubuntu 5.10 Breezy Badger, Kernel 2.6.10, g++ 4.0의 환경이었고, 그 결과 각각의 function의 return값이 같은 메모리를 가리키고 있었다,라고 결론을 얻었으며, 내 나름대로의 결론은 다음과 같다.

밑에서 글로 쓰기는 했지만, 그렇고 그런 책을 요즘 보고 있는데, 이런 내용이 나왔거든 -_-a

뭐, 줄여서 얘기하자면, 각 fuction의 로컬변수들이 잡히는 Stack Frame들이 운이 좋게[?] 같은 메모리에 잡혔다가 풀렸다가 한다는 말로 이해하고 있삼;

지금 궁금한건, 각 function에서 return을 해주고 나면, compiler가 알아서 이미 잡혀있던 stack 부분을 free해줄텐데, 그럼 정확한 값이 나올 수 없는거 아니야?

뭐, 본문에 제대로 써놓지는 않았지만, 가장 궁금했던 부분은 그거였어. 어떻게 compiler에서 알아서 free해줬을 부분을 잡아서 값을 넘겨줬는지.


하지만, 아직도 풀리지 않은 문제.
방금 학교 서버인 medusa.hanyang.ac.kr에서 같은 코드를 가지고 실행해 보았더니, 다음과 같은 결과값을 내뱉었다. 참고로, medusa는 SunOS 5.8, g++ 3.3.2의 환경이다.
address of x in fv() : 0xffbefae4
v = fv() : 1
address of x in fp() : 0xffbefae4
*p = fp() : 135952
address of x in fr() : 0xffbefae4
r = fr() : 1


그리고, 추가로, Windows XP SP2의 환경에서, g++ 3.4.2를 포함하고 있는 Dev-c++를 통해서는 다음과 같은 결과값을 얻었다.
address of x in fv() : 0x22ff44
v = fv() : 1
address of x in fp() : 0x22ff44
*p = fp() : 2288608
address of x in fr() : 0x22ff44
r = fr() : 1


우리는 두번째 function인 fp에서 리턴해준 값을 주목할 필요가 있다. 이미 한번의 테스트에서 1이 나왔기 때문에, 역시 내가 의도한 값은 이전의 테스트와 같은 값인 1이었다. 하지만, function fp는 두 시스템에서 모두 전혀 엉뚱한 값을 가리키고 있다. 과연 system-dependent 이기 때문에, 이런 값을 가르키게 되는 것일까, 아니면 다른 이유가 있는 것일까.

궁금증;

#include <iostream>
using namespace std;

int fv()
{
int x = 1;
cout << "address of x in fv() : " << &x << endl;

return x;
}

int* fp()
{
int x = 1;
cout << "address of x in fp() : " << &x << endl;

return &x;
}

int& fr()
{
int x = 1;
cout << "address of x in fr() : " << &x << endl;

return x;
}

int main()
{
int v = fv();
cout << "v = fv() : " << v << endl;
int* p = fp();
cout << "*p = fp() : " << *p << endl;
int r = fr();
cout << "r = fr() : " << r << endl;
}



컴파일해서 실행시켜보면,
address of x in fv() : 0xbfaef554
v = fv() : 1
address of x in fp() : 0xbfaef554
*p = fp() : 1
address of x in fr() : 0xbfaef554
r = fr() : 1



local 변수인 x의 address값이 동일하게 나온 이유는?
◀ PREV 12 NEXT ▶