본문 바로가기

교육 노트/C++ 기초강의

[C++ 때려잡기] C++ 기초강의 4-5 동적할당

2018/08/26 - [교육 노트/C++ 기초강의] - [C++ 때려잡기] C++ 기초강의 4-1 간단한 구조체

2018/08/26 - [교육 노트/C++ 기초강의] - [C++ 때려잡기] C++ 기초강의 4-2 배열과 다중배열

2018/08/26 - [교육 노트/C++ 기초강의] - [C++ 때려잡기] C++ 기초강의 4-3 마침내 포인터, 포인터 기초

2018/08/26 - [교육 노트/C++ 기초강의] - [C++ 때려잡기] C++ 기초강의 4-4 포인터와 배열의 상관관계, call by pointer



한 반을 관리하는 프로그램을 만들때

학생 배열을 만들것이다.


그러나 각 반마다 학생수가 달라

학생수를 입력받아 배열을 만들기로 하였다


#include <iostream>
using namespace std;

struct Student
{
    //내용
};

int main()
{
    int studentNumber;
    cin >> studentNumber;

    Student stuArr[studentNumber];

    return;
}




변수 studentNumber가 아닌 상수값이 들어가야한다고 나온다.

즉 상수값을 넣어야 배열 만들어지고

프로그램에서 미리 사이즈를 정해두어야 한다는 것이다.


따라서 학생수를 입력받아 그 크기만큼 배열을 만드는 것은 지금까지로는 불가능하다.


이유는 해당 변수가 만들어지는 과정이 "정적" 이기 때문이다

지금까지 만든 변수들은 전부 정적 변수이며 컴파일때 타입과 크기가 결정되고 생성된다.

정적인 배열은 크기가 컴파일 시간에 만들어지기떄문에 프로그램 실행중 (런타임) 중에는 입력받는 값으로 설정이 불가능하다.


대충 메모리 구조를 보면

요렇게 생겨먹었는데 여기서 지금까지 만든 정적인 변수들이 STACK 영역에 생성이된다.


그러나 우리가 원하는 것은 런타임도중에 사이즈를 정하여 그때 만들어내는 동적인 변수가 필요하다


그래서 있는것이 동적할당이다.



1. 동정할당


C++ 에서 동적할당은 new 키워드를 사용한다.



new를 통하여 변수를 만들면 메모리에서 heap 영역에 변수를 할당한다.

그러나  new로 동적으로 만들어진 변수는 지금까지 사용해온 정적인 변수처럼 이름을 가지고있지않는데

그냥 프로그램이 런타임도중 new를 만나는 순간 힙 영역에 공간만 할당하는것이다.


new키워드는 대신에 만들고 난뒤 heap영역에 만들어진 할당된 주소를 반환해준다.


따라서 해당 주소값을 받을 포인터를 만들고 해당 포인터를 통하여 동적할당된 값을 이용해야한다.


만약 int형 하나를 동적으로 할당하고 싶다면

int* grade = new int;


이런식으로 사용하면된다.

동적으로 배열을 만들고 싶으면

int* grade = new int[<number>];



여기서 동적할당은 런타임중에 만들어지기때문에 [] (배열첨자) 안에 들어갈 숫자는 변수여도 된다.

따라서


int main()
{
    int studentNumber;
    cin >> studentNumber;

    Student* stuArr = new Student[studentNumber];

    return;
}


다음과 같이 사용할수있다.


이렇게하면 동적으로 Student 배열을 만들고 해당 배열이 만들어진 주소를 반환해준다

배열의 이름은 어차피 포인터이기때문에 stuArr자체를 배열로써 사용하면된다




2. delete

정적 변수는 어차피  영역내에서 사용하고 끝나면 없어지는 변수이다.

그러나 동적 변수는 런타임어느때나 만들어지기 때문에 사용자가 따로 해당 메모리 할당을 풀어주어야 한다.



일반 변수는 delete, 배열의 경우 delete[] 를 해줘야한다.


힙 영역에 만들어진 변수는
delete를 하지 않으면 없어지지 않는다
따라서 변수 사용 후 delete를 반드시 해줘야 한다.
(메모리 leak의 주범)


이것을 delete하지 않으면 해당 변수는 이미사용이 끝났는데 쓸데없이 컴퓨터 메모리를 잡아먹고 있을것이다.



3. 이차원 동적 할당

이차원 배열을 사용했었는데

그럼 이차원 배열을 동적할당하려면 어떻게 해야할까


int** arr = int[][];


이렇게 하면 될까?


물론 아니고

각각 따로 할당을 해줘야 한다



이런 구조가 나오게 된다.

이것은 Int*의 배열 을 할당하고 각각의 int*에 int의 배열 을 만드는 것으로

여기서는 5x5를 만들었지만 for문의 안에 할당하는 방법만 바꾸면


이런식으로 할당할수도 있다.




ps. 이차원 배열을 만드는 조금 다른 방법도 존재하기는 한다.



따라서 delete도 따로따로 해줘야 한다.


이때 delete의 순서는 어떻게 해야할까?


당연히 new의 역순으로 해줘야한다.

즉 for문으로 하위 배열부터 제거하고

그다음 상위 배열을 제거해줘야한다.





실습


1. 프로그램을 참조하여 달팽이 배열을 만들어라


2. 가위바위보 게임에 유저와 유저점수를 구조체로 만들고 유저 포인터를 이용해서 로그인 기능을 만들어라




728x90