본문 바로가기
C++/기초

C++ 기초 : 가변 배열 (3)

글: 시플마 2024. 4. 7.

동적 할당된 공간에 새로운 데이터를 넣으려고 합니다.

 

근데 해당 공간이 꽉 차서 공간을 늘려줘야

데이터를 넣을 수 있는 상황입니다.

 

이 공간을 늘려주는 함수를 만들어 보죠.

 

 

아래와 같은 상황에서

 

pInt가 가리키고 있는 heap 영역의 공간에서

1번 인덱스 뒤에 공간을 추가하는 게 가능할까요?

 

불가능합니다. 

 

1번 인덱스 뒤에 주솟값은

 

5008번지겠죠? 그곳엔 어떤 데이터가 들어있을지 모릅니다.

 

그래서 무작정 1번 인덱스 뒤에 공간을 사용하려고 하면

프로그램 전체적으로 봤을 때 문제가 생길 수 있죠.

 

pInt를 통해서 5008번지에 1000을 넣으려고 했는데

그 공간이 '몬스터의 체력'으로 사용되고 있는 공간이라면

3.14의 값이어야 하는 몬스터의 체력이 갑자기 1000이 되는 

문제가 발생할 것입니다.

 

 

설령 5008번지 공간이 사용되고 있지 않더라도 문제가 발생합니다.

 

OS(Operating System, 운영체제)에서 5008번지 공간은 사용하지 

않는 공간으로 인식하는데 해당 공간에 접근하면

Heap Corruption(힙 손상)이 발생합니다.

 

 

이러한 이유들로 기존의 동적 할당된 공간을 넘어 데이터를

저장하고 싶다면 새로운 공간을 할당해줘야 합니다.

 

 

그래서 아래 그림처럼

 

새로운 공간을 동적 할당하고 해당 공간의 주솟값을 pInt에 저장하였습니다.

 

이러면 무슨 문제가 발생할까요?

 

기존의 있던 0과 1이라는 값에 다시 접근할 수 없게 되어

데이터를 잃어 버리는데 실제로 값은 남아 있기 때문에

메모리가 낭비되며 메모리 누수가 발생할 수도 있습니다.

 

 

Arr.h 파일에 

 

공간을 확장하는 Reallocate 함수를 선언하고

 

 

Arr.cpp 파일에 

 

정의하였습니다.

 

16

새로운 공간을 할당하자마자 pInt로 가리키지 말고

일단 새로운 포인터 변수 pNew를 만들어 새로운 공간을

가리키도록 합니다.

 

기존 공간이 꽉 차 공간을 확장하기 위해 Reallocate 함수가 호출되면 기존 공간에 +10만큼의 공간을 새로 할당할 것입니다.

 

 

19 ~ 22

새로 할당한 공간에 기존의 데이터를 처음부터 하나씩복사하기 위해 for문을 이용합니다.

 

해당 함수가 호출되었다는 것은 데이터가 iMaxCount만큼 찼다는 것이므로데이터 삽입 동작을 iMaxCount만큼 반복하여 복사해 주면 되겠죠?

 

 

지금까지의 동작을 그림으로 나타내면

 

위와 같습니다.

 

 

25

그리고 기존에 pInt를 통해 동적 할당하고 있던 메모리를 해제합니다.

 

 

28

이후 pInt가 새로운 동적 할당 공간을 가리키도록 pNew가 저장하고 있는 주솟값을 넘겨 줍니다.

 

 

31

새로 할당한 공간의 크기가 기존 2개에서 10만큼 늘어난 12개가 되었으니 iMaxCount의 값도 늘려 줍니다.

 

 

이후 Reallocate 함수가 종료되면서 

 

지역 변수(포인터 변수)인 pNew가 소멸됩니다.

 

 

이제 main.cpp에서 결과를 확인해 봅시다.

 

tArr형 객체 s는 선언된 후 InitArr 함수를 통해 초기화되었습니다.

 

처음 초기화되었을 때 동적 할당된 공간은 2개이므로

PushBack 함수를 통해 0 ~ 9 값을 대입하려고 하면

공간이 모자릅니다. 그래서 0 ~ 1을 대입한 후 2를 넣으려고 하면 

PushBack 함수 내부에 있는 Reallocate 함수가 작동하겠죠.

 

Reallocate 함수로 인해 기존 2개의 공간에서 10개 증가한

12개의 공간을 새로 할당하여 객체 s의 iMaxCount 값이 12가 될 것입니다.

 

그리고 0 ~ 9, 즉 10개의 값을 대입하였기 때문에 iCount의 값은 10이겠네요.

 

실행 결과 iMaxCount에는 12가 iCount에는 10이 들어간 것을 확인할 수 있습니다.

 

또한 객체 s 내부에, 동적 할당된 공간을 가리키고 있는 pInt를 통해 

동적 할당된 공간에 있는 값을 출력해 보니 0 ~ 9가 출력되었습니다.

 

값이 잘 대입된 것을 알 수 있네요.

 

 


 

 

아래 코드에서

 

23번째 줄을 보면 동적 할당된 공간을 초과하여

값을 대입하려고 할 때 호출되는 함수인 Reallocate 함수가 있습니다.

 

Reallocate 함수를 main.cpp에서 바로 사용할 수 있네요.

이는 main.cpp 파일이 Arr.h 파일을 참조하고 있고 Arr.h에는

Reallocate 함수의 선언이 있기 때문에 가능한 일입니다.

선언이 존재하므로 링크 과정에서 해당 함수의 정의까지

연결이 되기 때문에 사용할 수 있는 것이죠.

 

하지만 이는 의도한 바가 아니죠.

 

Reallocate 함수는 값을 대입하는 PushBack 함수를 통해서

작동하는 것이 의도였습니다. Arr.h 파일에서 Reallocate 함수의 선언을

없애 main.cpp에서 Reallocate 함수를 직접 사용할 수 없게 합시다.

 

 

 

강의 출처 : https://www.youtube.com/watch?v=PFc4g8mxOiI&list=PL4SIC1d_ab-aOxWPucn31NHkQvNPHK1D1&pp=iAQB


 

 

 

 

 

'C++ > 기초' 카테고리의 다른 글

C++ 기초 : 버블 정렬  (0) 2024.04.07
C++ 기초 : 리스트 (1)  (0) 2024.04.07
C++ 기초 : 가변 배열 (2)  (0) 2024.04.06
C++ 기초 : 가변 배열 (1)  (0) 2024.04.06
C++ 기초 : 동적 할당 (2)  (2) 2024.04.06