C++ 기초 정리 (지역, 전역, 정적(static) 및 메모리, 동적 할당)
태그: C++, Cpp, delete, memory, new, static
카테고리: Cpp
지역, 전역, 정적 및 메모리
지역, 전역, 정적(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++의 메모리 영역
-
스택 : 지역변수, 함수 인자의 메모리를 생성하는 공간이다.
함수가 종료되면 메모리를 제거한다.
크기 제한이 있다. - 데이터 : 전역변수, 정적변수의 메모리를 생성하는 공간이다.
- 초기화된 데이터 영역 : 초기값이 있는 전역/정적 변수
- BSS 영역 : 초기값이 없는 전역/정적 변수(자동으로 0 초기화된 변수들)
-
힙 : 동적할당된 메모리를 생성하는 공간이다.
(C언어 : malloc 등, C++ : new)
동적할당된 메모리는 프로그래머가 필요없을 때 반드시 제거를 해줘야 한다. - 코드 : 바이너리코드가 저장되는 영역이다. 함수도 코드이기 때문에 여기에 저장된다.
이런 특징 때문에 함수도 주소를 가질 수 있다. (=> 함수 포인터)
값 변경 불가(읽기전용)
동적 할당
동적할당: 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;
}
댓글남기기