TIL 2024/7/26

Sung Joo Lee·2024년 7월 26일

Local/Global Scope

  • 지역 범위
    • 블록 { } 내의 범위
    • 함수의 매개변수함수 본체 내에서만 존재함
    • 따라서 함수의 (복사된) 인자 및 지역 변수들은 함수의 실행 중에만 존재함
  • static 지역 변수
    • static 한정어를 사용해 예외 변수 지정 가능함
      • 예외 변수란 Scope에 상관 없이 여러 함수들이 공유 할 수 있는 변수
    • 초기화가 필요
  • 전역 변수
    • 함수 밖에 정의된 변수는 어디서나 접근 가능
    • 전역 변수는 사용하지 않는 것이 좋음
      • 전역 상수는 괜찮다 (어짜피 고정된 값이니)
#include <iostream>

using namespace std;

void staticLocalIncrement()
{
	static int num = 1;//예외 변수
	cout << "num: " << num << endl;
	num++;
	cout << "num: " << num << endl;
}

int main()
{
	staticLocalIncrement();
	staticLocalIncrement();
	staticLocalIncrement(); // num == 4

	return 0;
}

여기서 static int num으로 선언한 변수는 함수가 끝나도 초기화가 되지 않는다.

static으로 선언한 변수는 stack에 쌓이지 않고 메모리의 다른 영역에 생성된다. 이후 해당 static 변수가 다시 호출되었을 때는 초기화가 되지 않는다.

즉, static 변수지역변수가 아닌 예외 변수다!

Function Calls

  • 함수 호출의 동작방식
    • Fuction call stack

    • LIFO(Last in first out)

    • Stack Frame ( Activation Record) ****중요

      • 함수의 호출이 발생할 때마다 구분선이 생성
      • 함수의 지역 변수와 매개변수는 그 구분선 내에 생성됨
      • 함수의 호출이 끝나면 구분선 내의 메모리가 자동으로 해제됨
    • 스택은 유한하고, stack overflow 발생할 수 있음.

      메모리 구조

    • 일단 메모리 구조에 대한 파악을 먼저 해보자

  1. 코드공간

    1. 우리가 작성한 코드가 들어있는 공간
  2. static 변수, 전역변수 , string 리터럴

    1. 해당 변수들이 저장됨! ( static 변수는 stack에 저장되는 것 이 아니다)
  3. 스택

    1. 빠르지만 저장 공간의 크기가 작음
    2. 메모리가 자동으로 해제됨
    1. 느리지만 저장 공간의 크기가 작음
    2. 메모리를 직접 해제 해주어야함
      1. 해제하지 않을 시 메모리 누수가 발생 할 수 있음

이해를 한번 해보자!

#include <iostream>

using namespace std;

int func2(int x, int y, int z)
{
	x += y + z;
	return x;
}

int func1(int a, int b)
{
	int result;
	result = a + b;
	result = func2(result, a, b);
	return result;
}

int main()
{
	int x = 10;
	int y = 20;
	int z;
	z = func1(x, y);
	cout << z << endl;
	return 0;

}
  • main 함수부터 시작되어 int형 변수 x, y, z 가 선언이 되고 func1(x,y)가 호출된다.

  • 이때의 동작과정을 같이 봐보자.

  • 이게 func1() 함수가 호출이 되기 전이고, CC의 값이 무엇인가 하고 의문을 가질 수 있다.

  • 위의 코드를 보면 func2의 동작이 끝나고 fun1의 동작이 끝나고 main의 z에 값을 알 수 있다.

  • 즉, 위의 func2의 return된 값이 복사되고..func1의 return 값이 복사 될때까지는 메모리에 쓰레기 값이 존재한다.

  • fucn1 함수가 호출된 이후의 메모리 그림이다.

  • 이전에 말했던 것을 기억하나? call-by-value의 개념이 기억난다면 ‘아! 지금 그 개념이 들어가 있구나!’ 하고 알아채면 GOOD이다.

    • func1의 매개변수의 값에 main 함수의 x ,y의 값이 ‘복사’되어 들어왔다.

  • 이제 위의 그림이 func2가 호출이 된 이후의 그림이다.

  • 이제 이후의 x의 값은 60으로 바뀌고 자신을 호출한 지점으로 실행 흐름이 되돌아간다.

    • 자기 자신을 호출한 곳에 ‘화살표’가 존재한다고 생각해 보자!
    • 호출된 ‘함수의 동작이 끝난 뒤’ 다시 돌아가 해당 지점부터 다시 시작!
  • 아래의 그림을 한번 보도록 하자

  • 위의 내용을 이해하면서 직접 한번 다시 해보자.
  • 모든 동작이 끝나면 스택 메모리가 전부 해제된다.
profile
개발로그

0개의 댓글