기본 콘텐츠로 건너뛰기

임시변수와 스택

C/C++을 하다보면 자기도 모르는 사이에 임시변수를 쓰곤하는데, 대부분 암묵적 형변환에 의해서이다. 이때 발생하는 임시변수는 어디에 만들어지는 것일까? 보통 함수 내 자동 변수들은 프로세스 스택에 만들어지는 것으로 알고 있다. 정말 그런지 알아봐야겠다.

#include <iostream>
#include <string>
using namespace std;


volatile bool gTest(true);
const char gString[] = "Hello, world!";

template<typename _T>
void
_func(const _T& v)
{
    cerr << "Temporary variable: " << (void*)&v << endl;
    cerr << "Temporary buffer: " << (void*)(v.c_str()) << endl;
}

template<typename _T>
void
callStack(void)
{
    _T local1;

    cerr << "Type ID: " << typeid(local1).name() << endl;
    cerr << "Local1 variable: " << (void*)&local1 << endl;
    cerr << "Local1 buffer: " << (void*)(local1.c_str()) << endl;

    if ( gTest )
    {
        _T local2;
        cerr << "Local2 variable: " << (void*)&local2 << endl;
        cerr << "Local2 buffer: " << (void*)(local2.c_str()) << endl;
    }

    _T local3;
    cerr << "Local3 variable: " << (void*)&local3 << endl;
    cerr << "Local3 buffer: " << (void*)(local3.c_str()) << endl;

    _func<_T>(gString);

    _T* heap1(new _T);
    cerr << "Heap1 variable: " << (void*)heap1 << endl;
    cerr << "Heap1 buffer: " << (void*)(heap1->c_str()) << endl;
    delete heap1;
}

int
main(int,char**)
{
    callStack<string>();
    return 0;
}

C++ 문법을 쓴 것이기 때문에 C++ 컴파일러로 컴파일하자. 결과는?
$ g++ -o stack stack.cpp
$ ./stack
Type ID: Ss
Local1 variable: 0xbff08ba0
Local1 buffer: 0x804a6ac
Local2 variable: 0xbff08b80
Local2 buffer: 0x804a6ac
Local3 variable: 0xbff08b80
Local3 buffer: 0x804a6ac
Temporary variable: 0xbff08b70
Temporary buffer: 0x9d73024
Heap1 variable: 0x9d73038
Heap1 buffer: 0x804a6ac
함수 내 모든 자동 변수와 임시 변수는 메모리 주소를 확인한 결과 스택에 만들어졌다.
Local? buffer와 Heap1 buffer가 같은 까닭은 기본 생성자로 만들어진 std::string 내부 문자열 포인터는 이미 만들어진 빈문자열 공간을 가르키는 것 같다.다만 Temporary buffer만이 assign이 일어나면 다른 주소를 할당해서 사용하였기 때문에 Heap1 variable과 비슷한 영역을 가진다.

덧글: 괜찮은 링크 발견!! 함수 호출 규약

댓글

이 블로그의 인기 게시물

Winget 해시 무시하기

가끔씩 Winget 에서 패키지를 다운로드 했을 때, "설치 관리자 해시가 일치하지 않습니다." 오류가 뜰 때가 있다. 보안 이슈가 있지만, 그냥 무시하고 싶을 때, 아래 순서로 무시해준다. 관리자 권한 winget settings --enable InstallerHashOverride 설치 winget install --ignore-security-hash --id NirSoft.NirCmd