Publish:

태그: , , , , ,

카테고리:


지역, 전역, 정적 및 메모리

지역, 전역, 정적(static)

1
2
3
4
5
6
7
8
9
// main.cpp
int gNumber;                        // 전역 변수. 자동으로 0으로 초기화 됨.

int main()
{
    int number;                     // 지역 변수

    return 0;
}
  • 지역변수 : 함수 안에서 선언하는 변수.
    지역변수는 선언된 함수 안에서 사용할 수 있고 함수가 종료되면 메모리에서 제거된다.

  • 전역변수 : 함수 바깥에 선언하는 변수.
    전역변수가 선언된 아래의 모든 곳에서 전역변수에 접근하여 사용할 수 있다.
    전역변수는 초기화 하지 않을 경우 자동으로 0으로 초기화된다.

  • 정적변수 : static 키워드를 이용하여 선언된 변수이다.
    전역변수, 지역변수 모두 static 키워드를 붙일 수 있다.

지역 변수에 static을 붙여서 변수를 선언하면,
해당 변수는 초기화 안 할 경우 0으로 자동으로 초기화가 되고, 초기화 코드는 단 1번만 동작한다.
함수가 종료되어도 메모리가 유지된다.

정적 변수, 전역 변수는 프로그램이 종료될 때 메모리가 제거된다. (그전까지 계속 남아있다)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 코드영역에 만들어짐 (함수니까)
void Test()
{
	// 정적 변수의 초기화 코드는 1번만 동작하므로,
    // Test가 처음 호출될 때 한번 실행되고 메모리가 유지된다.
	static int number = 200;

	printf("number : %d\n", number);

	number++;
}

void main()
{
	// 스택영역에 만들어짐 (지역변수)
	int number = 111;

	Test();						// 200 출력
	Test();						// 201 출력
	Test();						// ...
	Test();
	Test();						// 204 출력
}

C++의 메모리 영역

  1. 스택 : 지역변수, 함수 인자의 메모리를 생성하는 공간이다.
    함수가 종료되면 메모리를 제거한다.
    크기 제한이 있다.

  2. 데이터 : 전역변수, 정적변수의 메모리를 생성하는 공간이다.
    • 초기화된 데이터 영역 : 초기값이 있는 전역/정적 변수
    • BSS 영역 : 초기값이 없는 전역/정적 변수(자동으로 0 초기화된 변수들)
  3. 힙 : 동적할당된 메모리를 생성하는 공간이다.
    (C언어 : malloc 등, C++ : new)
    동적할당된 메모리는 프로그래머가 필요없을 때 반드시 제거를 해줘야 한다.

  4. 코드 : 바이너리코드가 저장되는 영역이다. 함수도 코드이기 때문에 여기에 저장된다.
    이런 특징 때문에 함수도 주소를 가질 수 있다. (=> 함수 포인터)
    값 변경 불가(읽기전용)

동적 할당

동적할당: new를 사용하여 동적할당을 하고, delete를 사용하여 동적할당된 메모리를 제거할 수 있다.

  • new와 delete는 연산자이다.
  • new를 이용해서 생성한 메모리를 제거하지 않으면, 메모리 릭이 발생하게 된다.
  • new 변수타입; 을 해주면, 변수 타입의 크기만큼 힙에 메모리를 생성하고 그 주소를 반환해준다. delete 주소; 를 해주면 해당 주소를 메모리 해제해준다. 반드시 동적할당 된 주소만 넣어주어야 한다.
  • C언어에서는 malloc, free 함수를 이용해서 동적할당하고 해제한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int* numAddr = new int;		// 힙에 메모리 4바이트 만들고 주소 리턴
                            // 주소를 반환하니 포인터 타입으로 받아줄 수 있다.
                            // 이 한 줄에선 12바이트가 생성된다.
                            // new int 하여 힙에 4바이트가 생성되고,
                            // 왼쪽에 포인터 변수 만들었으니 스택에 8바이트가 생성된다.

*numAddr = 300;
delete numAddr;



int* array = new int[30];   // 동적 배열을 만들고 그 시작 주소를 반환해준다.

array[4] = 10;
delete[] array;

이중 포인터와 동적 할당

이중 포인터의 사용법
함수 안에서 내가 원하는 메모리를 할당해서, 함수를 호출한 뒤에 그 메모리를 넘겨주고 싶을 때 사용할 수 있다.
이중 포인터를 하지 않고 그냥 포인터로 하면,
함수 밖을 나갔을 때 함수 안에서 동적할당된 메모리에 접근할 방법이 사라지니까.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
void Alloc(int** addr)
{
    *addr = new int;
}

int main()
{
    int* addr = nullptr;			
    Alloc(&addr);				

    *addr = 500;

    delete addr;
}

call by address, call by reference, call by value


이슈 및 공부한 것을 기록해두는 개인 블로그 입니다. 댓글, 피드백 환영합니다 🙂

Update:

댓글남기기