assortrock

c++ 10일차 1부

solie75 2022. 5. 21. 18:18

[구조체와 포인터를 이용한 동적 배열 할당 예시]

 

<main.cpp>

#include <stdio.h>
#include <iostream>
#include "DynamicArray.h"

int main()
{
	//동적 객체 배열 선언
	tag_DynamicArray arr = {};

	//배열 초기화
	InitArray(&arr);


	//// 초기화한 데이터 출력
	//for (int i = 0; i < arr.iArrayMax; i++)
	//{
	//	printf("초기화한 데이터 : %d\n", arr.pData[i]);
	//}

	//배열에 데이터 입력
	for (int i = 0; i < 100; ++i)
	{
		Push(&arr, i + 1);
	}

	//입력한 데이터 출력해보기
	for (int i = 0; i < arr.iCurCount; i++)
	{
		printf("입력한 데이터 : %d\n", arr.pData[i]);
	}

	//배열이 사용하던 Heap메모리 영역 해제
	ReleaseArray(&arr);

}

 

<DynamicArray.h>

#pragma once

struct tag_DynamicArray
{
	int* pData;  // 할당 받는 배열의 주소가 들어갈 포인터
	int	iArrayMax;  // 데이터 최대 개수
	int iCurCount;  // 데이터 현재 개수
};

//초기화 함수
void InitArray(tag_DynamicArray* _target);  // 여기에서 _target은 포인터

// 데이터 입력 함수
void Push(tag_DynamicArray* _target, int _data);

//해제 함수
void ReleaseArray(tag_DynamicArray* _target);

 

<DynamicArray.cpp>

#include <iostream>

#include "DynamicArray.h"

void InitArray(tag_DynamicArray* _target)  // 순서 1
{
	_target->iArrayMax = 2;  // 최대 크기 // 화살표 연산자  우측의 매개변수가 좌측에 속해있다.
	_target->pData = (int*)malloc(sizeof(int) * _target->iArrayMax); // iArrayMax만큼의 크기의 메모리를 할당 받는다
	_target->iCurCount = 0;  // 현재 인덱스
}

void Realloc(tag_DynamicArray* _target)  // 순서 3
{
	// 확장 규칙은 기존 개수의 2배로 한다.
	int NextMaxCount = _target->iArrayMax * 2;

	//확장된 크기만큼 동적할당 해서 힙메모리에 저장
	int* pNewAdress = (int*)malloc(sizeof(int) * NextMaxCount);

	//기존 공간에 있던 데이터를 새로 확장한 곳으로 옮긴다.
	for (int i = 0; i < _target->iArrayMax; ++i)
	{
		pNewAdress[i] = _target->pData[i];  // Q. 이 함수가 처음으로 호출될 때, NextMaxCount가 4일때 pNewAdress[2], pNewAdress[3]에 담기는 값은 무엇인가?
	}

	// 기존 공간을 메모리 해제한다.
	free(_target->pData);

	//배열의 데이터를 관리하는 주소를 새로 할당 받은 곳으로 갱신한다.
	_target -> pData = pNewAdress;

	//데이터 최대 허용 개수 갱신
	_target->iArrayMax = NextMaxCount;
}

void Push(tag_DynamicArray* _target, int _data)  // 순서 2
{
	// 공간이 부족한지 확인( 현재 데이터 개수가 최대 개수를 넘어선 상황)
	if (_target->iArrayMax <= _target->iCurCount)
	{
		Realloc(_target); // iCurCount 가 최대 크기를 넘어서 이 함수를 호출할 때( 할당받은 메모리가 다 채워졌을 때) 또 할당 받는다.
	}
	// main 의 push 함수에 대한 for 반복문으로 _data 는 1부터100까지 올림차순으로 하나씩 들어오고 후위 증산 연산자는 이 줄에서 맨 마지막에 처리한다
	_target->pData[_target->iCurCount++] = _data;  //_data가 1인 경우 (for 문에서 i 가 0일때) pData[0]에 정수 '1'이 대입된다.
}

void ReleaseArray(tag_DynamicArray* _target)  // 순서 4
{
	free(_target->pData);
}

[경고]

DynamicArray.cpp 에서 기존 데이터를 임시 새로운 데이터 공간에 옮길 때 발생

버퍼 오버런이란?

의문 : 이 함수(Realloc)가 처음으로 호출될 때, NextMaxCount가 4일때 pNewAdress[2], pNewAdress[3]에 담기는 값은 무엇인가?