기타 지식

C++) 동적 할당에 대해 알아보자.

안녕 개붕이들아.

며칠동안 내가 올렸던 글들을 읽어봤는데,

너무 엉망진창이더라...

그래서 다시 마음잡고 한번 글을 써볼까 해.
 

이번에는 동적 할당에 대해 알아볼거야.

프로그래밍에서 가장 중요한 요소는 변수야.

전에 말했다싶이, 변수에는 여러 값들을 담아놓을 수 있어.

int a = 234; 같이 명령어를 치면, 메모리에 234 같은 숫자들을 저장해 놓을 수 있는거야.

 

사실 이 변수들에는 비밀이 있어.

컴퓨터는 이런 변수들을 선언될 때 마다 메모리 공간을 찾아서 만들지 않고,

프로그램이 처음 시작될 때, 사용되는 변수들의 크기만큼 미리 메모리에 공간을 만들어 놓는거야.

이런걸 정적할당 이라고 불러.

 

그러면 동적할당은 뭘까?

동적할당은, 프로그램이 실행되는 도중에 메모리에 공간을 만드는거야.

 

정리하자면,

정적할당 - 프로그램이 실행되자마자 사용되는 메모리 크기만큼 미리 메모리에 공간을 만들어놓고 프로그램 실행.

동적할당 - 프로그램이 실행되는 도중에 필요한만큼 메모리에 공간을 만들면서 실행.

 

그럼 동적할당은 왜 사용하는걸까?

여러가지 이유들이 있는데 크게 두 가지가 있어.

 

1. 배열의 크기를 상황에 맞게 바꾸고 싶은 경우

2. 메모리 공간을 최소한으로 사용하고 싶은 경우

 

배열의 크기를 상황에 맞게 바꾸고 싶다는게 뭔 소리일까?

예를 들어서, 개붕이의 친구들 전화번호를 저장하는 프로그램을 만들어보자.

 

int phoneNumbers[5];
int arrAt = 0;
int input = 0;

while (true) {
    std::cin >> input;
    phoneNumbers[arrAt] = input;
    arrAt++;
}

 

처음에 개붕이는 아싸니깐 친구들 전화번호가 5개를 넘어가지 않을꺼라고 예상했어.

그래서 배열 크기를 5로 정해버린거야.

 

근데 그런 개붕이에게 신이 기적을 내리셔서 친구가 6명이 된거야!

근데 배열 크기는 5로 정해버려서 친구 한명을 더 추가하면 프로그램에서 오류가 나버려.

이런 상황을 해결하기 위해서 우리 똑똑한 개붕이는 배열 크기를 100으로 했어!

 

근데 여기서 문제가 생겼어.

신이 노하셔서 개붕이에게 친구를 더이상 주지 않은거야.

그러면 개붕이가 phoneNumbers 배열에 담는 친구는 6명 뿐이지만, 배열 크기는 100이나 되어버리는 완전한 낭비가 되어버렸지?

 

이런 상황을 피하기 위해 나온게 바로 동적할당이야.

처음 배열 크기는 1로 하지만, 개붕이 친구가 한명씩 늘 때 마다 배열 크기를 늘리면?

그러면 개붕이 친구가 1명이던, 10명이던, 100명이던, 1000명이던 오류 없이, 또 메모리 공간을 아끼면서 배열에 친구들 전화번호를 넣을 수 있겠지?

 

이제 동적할당을 어떻게 하는지 알아보자.

 

우선은 일반적인 변수부터 동적할당 해보자.

int* num = new int;

이렇게 하면 돼.

 

물론,

int* num;

num = new int;

같은 방식으로 하는것도 가능해.

 

포인터 변수를 선언한 후,

그 포인터 변수에 new int 라는걸 넣어줬어.

 

그럼 new int 는 무슨 명령어일까?

new 는 바로 메모리에 공간을 만드는 명령어야.

 

new 자료형;

방식으로 사용해.

 

응용하자면,

char* character = new char;

bool* boolean = new bool;

double* decimal = new double;

같은것도 가능한거지.

 

동적할당을 한 후에는,

일반적인 포인터 변수처럼 사용하면 돼!

 

int num = new int;

num = 34;

 

같이 말야.

 

근데말야, 여기에는 큰 문제가 하나 있어.

이 동적할당이란걸 해주면, 프로그램이 끝나기 전 까지는 메모리에 계속 변수가 남아있는거야.

 

예를 들어서,

while (true) {

    int* abc = new int;

}

 

같이 해주면 무슨 일이 일어날까?

capture.png

쫘잔!

프로그램이 사용하고 있는 메모리가 2GB 까지 올라가다가 결국은 프로그램이 꺼져버렸어.

 

이렇게 동적할당한 메모리를 해제 해주지 않으면, 메모리 누수 라는 일이 일어나버려.

그럼 이제 동적할당한 메모리를 해제 해보자!

 

제거가 영어로 뭐지?

delete!

그럼 이걸 그대로 쓰면 메모리를 해제할 수 있어.

 

int* abc = new int;

delete abc;

 

이렇게 해주면 abc 에 할당되어있는 메모리를 제거할 수 있는거야!

 

delete 변수이름;

같은 방법으로 사용 가능하단거지!

 

그럼 delete abc를 넣은 상태로 아까전의 코드를 실행해보자!

while (true) {

    int* abc = new int;

    delete abc;

}

 

capture.png

오오

아까전의 2GB 와는 다르게, 801KB 만 사용하고 있어!

그러면서 프로그램도 죽지 않고있지!

 

delete 명령어의 효과를 좀 더 다이나믹하게 보기 위해서,

약간 선행을 해보자!

 

while (true) {
    char* a = new char[10000000];
    Sleep(1000);
    delete[] a;
    Sleep(1000);
}

 

(대충 1초 간격으로 10000000크기의 char 배열을 동적할당하고 지우는 프로그램)

 

capture.png

이것좀 봐바..

메모리 사용률 그래프가 너무 예뻐서 눈물이 나올것 같아..

 

capture.png

CMD 에서만 하던 별 피라미드를 동적할당 그래프로 한다던지

 

capture.png

sin 그래프를 메모리 사용률 그래프에서 본다던지..

너무 예쁘지 않아?

어서 이런것들을 해보기 위해 동적할당에 대해 더 배워보자!

 

이번에는 배열을 동적할당 해볼거야!

 

int* arr = new int[100];

어라? 전에 배운거랑 다른점이 하나뿐이지?

배열을 동적할당 하는 방법은 간단해.

 

new 자료형[배열크기];

이렇게만 해주면 된단 말씀!

 

거기에다가 이 배열 동적할당에 있어서 놀라운 점은,

배열 크기에 변수를 넣을 수 있어!

 

int arrSize = 10;

int* arr = new int[arrSize];

 

가 가능하단거지!

 

하지만, 일반적인 변수의 동적할당과 마찬가지로,

배열 동적할당도 사용하고 나서 지우지 않으면 누수가 발생해.

그것도 배열 동적할당이라 훨씬 더 빠른 속도로!!

 

그럼 동적할당된 배열은 어떻게 해제할까?

아까 delete 변수이름 해줬던거 기억하지?

동적할당된 배열을 지우는건,

 

delete[] 변수이름;

방식으로 해주면 돼!
간단하지?

 

예를 들어보자면,

 

int* arr = new int[100];

delete[] arr;

 

같이 해주면, arr 에 100 크기의 배열을 할당하고, arr 에 할당된 배열을 지우는거지!

 

그럼 다시 처음의 개붕이 문제로 돌아와서,

개붕이 전화번호부를 한번 만들어보자!

 

int* phoneNumbers = nullptr;
int* tempPhoneNumbers = nullptr;

 

int arrAt = 0;
int input = 0;

while (true) {
    std::cin >> input;

 

    tempPhoneNumbers = phoneNumbers;
    phoneNumbers = new int[arrAt + 1];

 

    for (int at = 0; at < arrAt; at++) {
        phoneNumbers[at] = tempPhoneNumbers[at];
    }


    delete[] tempPhoneNumbers;

 

    phoneNumbers[arrAt] = input;
    arrAt++;
}

 

짜잔! 이렇게 해서 막상 전화번호는 넣을 수 없는 개붕이 전화번호부 완성이야!

몰라 예제 왜 이리 어려운거 고른걸까

 

어쨋든,

이게 바로 동적할당이야.

 

동적할당의 두번째 장점이였던 메모리 공간을 아낄 수 있다 기억해?

이제 이거의 예시를 한번 보자.

 

int num;

num = 111 * 222;

std::cout << num << std::endl;

 

(대충 num 사용하지 않는 엄청 긴 코드 실행)

 

이런 코드가 있다고 생각해보자.

 

그러면 num은 코드 가장 앞에서만 사용하고, 뒤에서는 전혀 사용하지 않지만 계속 메모리에서 자리를 차지하고 있어.

아깝잖아?

 

이런 아주 조금의 메모리 낭비도 아끼기 위해서 동적할당이 있어.

저 코드를 동적할당으로 최적화 하면...

 

int* num;

num = new int;

 

*num = 111 * 222;

std::cout << *num << std::endl;

delete num;

 

같은게 가능하겠지?

 

메모리 공간을 훨씬 더 아낄 수 있는거지.

뭐 그렇다고.

 

사실

{

int num;

num = 111 * 222;

std::cout << num << std::endl;

}

 

하면 다 해결되는 문제인데 말야.

뭐하러 동적할당 하는지 몰라

 

뭐. 이제 글쓰기 귀찮다.

이정도면 대충 알겠지?

 

마지막으로 정리해보자면,

new 자료형;  //변수 동적할당

new 자료형[배열크기]; //배열 동적할당

 

delete 변수이름; //변수에 할당되어있는 메모리를 제거

delete[] 변수이름; //배열에 할당되어있는 메모리를 제거

 

개붕이들아 즐거운 C++ 하고,

새해 복 많이 받아.

31개의 댓글

2021.02.13

int*랑 int는 같은 변수 종류가 아니라는 걸 설명해야 사람들이 포인터라는 개념에 대해 헷갈려 하지 않을 듯

 

int*는 정수형 변수의 주소값을 저장하는 자료형이고

int는 정수를 저장하는 자료형이고 ㅇㅇ...

 

사실 C계열 언어에서 사람들이 포인터에 헷갈려 하는건 이거 때문인거 같음

 

int*와 int는 사실 다른 건데, *하나만 빼고 보면 생긴 건 거의 비슷해서

이게 뭐가 다른거임? 하는 거라..

0
2021.02.13

학과 수업으로 C언어 처음 배울때 동적할당때문에 개짜증났던거 ㄹㅇ

malloc calloc 씨~~발련들아

1
2021.02.13
@세기 중갑옷

참고로 작성자는 malloc 사용법을 모른다 (???)

0
2021.02.13
@쿄코

ㅇㅇ c 였으면 delete 가 아니라 free 였겟지

c++ 글인데 뭐

이상할거없음 ㅎㅎ

0
NML
2021.02.13
@세기 중갑옷

멀록멀럭 으엌

0
2021.02.13

아 왜 동적할당인데 malloc 이 안 나왔지, 아 킹 받네

하고 봤더니 c++ 이구나 미안~

0

씨플플 너무좋아 고마웡!

0
2021.02.13

memory alignment 에 대해서도 다뤄봐

0
2021.02.13

고급개발자 되려면 씨언어계열 잘 다뤄야 됨?

0
2021.02.13
@우유빚깔

저급 개발자여서 나도 모르겠어

0
2021.02.13
@우유빚깔

고급개발자라기보다는 저레벨 개발자가 C계열 잘 다뤄야함

고급개발자는 자바개발자도 연차 쌓고 실력 다지면 되는거(단, 퍼센티지 따져보면 중급 개발자 중에 약 10% 정도만 고급 개발자가 된다고 함)

저레벨은 바이오스나 엔진같이 하드웨어와 가까운 것들과 관련된 거임 초봉부터 개쌤

0
2021.02.13
@세기 중갑옷

저레벨이라면 능력치가 낮다는게 아니라 언어 단계에서 로우 레벨을 말하는거지?

0
2021.02.13
@우유빚깔

맞음

0
2021.02.13
@우유빚깔

메모리를 극한으로 효율적으로 사용하도록 하는 곳이라 메모리 직접 접근이 가능한 언어를 써야하거든

 

0
2021.02.13
@세기 중갑옷

임베디드 개발에는 그런경우도 많지만.... PC 기반 개발에서는 이미 메모리 차고 넘쳐서 그 정돈 아닙니다...ㅜㅜ

우리 자라나는 새싹들한테 C++ 공포증 심어주지 마세욧!

초보 개발자분들 C++ 재밌고 일자리 많습니다. 츄라이 츄라이!

0
2021.02.13
@개드립회원

하지만.....영상처리배우다가 도망갔다구....

0
2021.02.13
@세기 중갑옷

아니 그렇게 재밌는 CV 를 하면서 관뒀다고 ?!??!??!?

0
2021.02.13
@관음증

CV가 재밌긴한데 동시에 굇수들이 해놓은 작업물들보고 자신감이 나락으로 떨어지드라

0
2021.02.13
@개드립회원

맞아 정말 타이트하게 MCU 잡는거면 메모리 극한으로 해야한다고 하는데 거의 안그럼

요즘엔 저렴한 mcu도 메모리를 수십kb나 빵빵하게 지원하고 정말 복잡한 기능을 넣는게 아니면 괜찮음

 

C를 쓰는 이유도 그냥 지금까지 써왔으니까 쓰는거고 포인터를 쓰는 이유도 레지스터에 직접 접근하기 위해서 그러는거지 딱히 뭐가 있는건 아님

0
2021.02.13

처음에 정적할당의 경우에는 프로그램의 첫 시작에서 할당을 하는게아니라 각 함수의 프롤로그에서 할당합니다

0
2021.02.13
@qwerty9999

그리고 글로벌 변수의 경우엔 컴파일 타임에 컴파일 타겟에 맞는 헤더에 공간을 할당해놓습니다

0
2021.02.13

돌아왔구나 오태식이

이제 라이브러리 설명해줘

0
2021.02.13

고맙다 개붕아

이 글 읽고 구글 입사제의 받았다 고맙다

0
2021.02.13
@빌런히어로

아 나도 대려가~

0

해제된 메모리에 접근했을 때 발생하는 문제점이랑 c++11 이후부터 추가된 스마트 포인터도 같이 설명해주면 좋을 거 같아잉

0
2021.02.14

왛 나 이해했써

스크립트만 쓰고 개발툴도 요상한거라 자신없었는데

올려준거 슬슬보니까 c++금방하겠당

0
2021.02.14

메모리 사용률 그래프는 어디서 봐?

0
2021.02.14
@초보댓글러

F5 누르면 디버깅 모드로 들어가지는데,

거기서 뭐더라 뭐시기 정보 하면서 옆에 뜰껀데..

0
2021.02.14
@쿄코

고마워 ~

0
2021.02.16

포인터 설명할꺼면 stack과 heap도 설명해야하지않을까

0
무분별한 사용은 차단될 수 있습니다.
번호 제목 글쓴이 추천 수 날짜
12413 [호러 괴담] [살인자 이야기] 그녀는 왜 일본 최고령 여성 사형수가 되었나 8 그그그그 5 1 일 전
12412 [기타 지식] 최근 지각변동이 일어나는 국내 항공업계 (수정판) 14 K1A1 19 2 일 전
12411 [역사] 인류의 기원 (3) 식별불해 4 2 일 전
12410 [호러 괴담] [살인자 이야기] 재벌 3세의 아내가 사라졌다? 그리고 밝혀지... 그그그그 4 4 일 전
12409 [호러 괴담] [살인자 이야기] 의붓아버지의 컴퓨터에서 발견한 사진 3 그그그그 7 6 일 전
12408 [기타 지식] 도카이촌 방사능 누출사고 실제 영상 21 ASI 2 6 일 전
12407 [역사] 지도로 보는 정사 삼국지 ver2 19 FishAndMaps 14 8 일 전
12406 [기타 지식] 웹툰 나이트런의 세계관 및 설정 - 지구 2부 21 Mtrap 8 6 일 전
12405 [기타 지식] 100년을 시간을 넘어서 유행한 칵테일, 사제락편 - 바텐더 개... 5 지나가는김개붕 1 8 일 전
12404 [기타 지식] 오이...좋아하세요? 오이 칵테일 아이리쉬 메이드편 - 바텐더... 3 지나가는김개붕 2 10 일 전
12403 [기타 지식] 웹툰 나이트런의 세계관 및 설정 - 지구 1부 31 Mtrap 13 10 일 전
12402 [기타 지식] 칵테일의 근본, 올드 패션드편 - 바텐더 개붕이의 술 이야기 15 지나가는김개붕 14 10 일 전
12401 [기타 지식] 웹툰 나이트런의 세계관 및 설정 - 인류 2부 22 Mtrap 14 10 일 전
12400 [기타 지식] 웹툰 나이트런의 세계관 및 설정 - 인류 1부 13 Mtrap 20 10 일 전
12399 [역사] 군사첩보 실패의 교과서-욤 키푸르(完) 1 綠象 1 9 일 전
12398 [호러 괴담] [살인자 이야기] 미치도록 잡고 싶었다. 체포되기까지 28년이... 1 그그그그 6 11 일 전
12397 [역사] 아편 전쟁 실제 후기의 후기 3 carrera 13 12 일 전
12396 [과학] 경계선 지능이 700만 있다는 기사들에 대해 34 LinkedList 10 12 일 전
12395 [호러 괴담] [살인자 이야기] 두 아내 모두 욕조에서 술을 마시고 익사했... 그그그그 2 15 일 전
12394 [기타 지식] 서부 개척시대에 만들어진 칵테일, 카우보이 그리고 프레리 ... 3 지나가는김개붕 5 15 일 전