다른 데이터가 들어있는 heap 영역을 침범해서 데이터를 저장하거나?, 사용되지 않는 메모리 영역을 참조하면 일어남
그 침범당한 부분에 저장된 변수를 가져오는 코드에 문제가 생김, 다른 사람 코드에서 문제를 일으킬 수도 있음
이걸 해결하려면?
2칸이 꽉 차면 저장공간을 2칸 늘리는게 아니라?
2 + 2 = 4 --> 즉 4개의 데이터를 넣을 메모리공간을 아예 처음부터 새로 받아야함
#pragma once
typedef struct _tagArr
{
int* pInt;
int iCount;
int iMaxCount;
}tArr;
// 배열 초기화 함수
void InitArr(tArr* _pArr);
// 데이터 추가 함수
void PushBack(tArr* _pArr, int _iData);
// 공간 추가 확장
// void Reallocate(tArr* _pArr);
// 이걸 헤더파일에서 주석처리한 이유는?
// main 함수에서 만약에 이걸 호출하면 배열이 가득차지도 않았는데 뜬금없이 크기가 2배 증가함
// 그래서 main 함수에서 사용되지 못하게 하려고 주석처리 해준거임
// 어차피 cpp 파일에서는 이 함수가 구현되어 있으므로 아무 문제 없음, main 함수에서 사용되지 않는 함수는 이렇게 막아줄 수도 있음
// 배열 메모리 해제 함수
void ReleaseArr(tArr* _pArr);
#include "Arr.h"
#include <iostream>
void InitArr(tArr* _pArr)
{
_pArr->pInt = (int*)malloc(sizeof(int) * 2);
_pArr->iCount = 0;
_pArr->iMaxCount = 2;
}
void Reallocate(tArr* _pArr)
{
// 1. 2배 더 큰 공간을 할당한다.
int* pNew = (int*)malloc(_pArr->iMaxCount * 2 * sizeof(int));
// pInt에 바로 넣어버리면 기존의 주소는 아무도 가리키지 않음
// 데이터가 날라감
// 2. 기존 공간에 있던 데이터들을 새로 할당한 공간으로 복사시킨다.
for (int i = 0; i < _pArr->iCount; ++i)
{
pNew[i] = _pArr->pInt[i];
}
// 3. 기존 공간은 메모리 해제
free(_pArr->pInt);
// 4. 배열에 새로 할당된 공간을 가리키게 한다.
_pArr->pInt = pNew;
// 5. iMaxCount 변경점 적용
_pArr->iMaxCount *= 2;
// 호출될때마다 영역크기를 얼마나 늘릴지는 만든 사람이 정하는 것
// 여기서는 2배씩 늘리기로 함
}
void PushBack(tArr* _pArr, int _iData)
{
// 힙 영역에 할당한 공간이 다 참
if (_pArr->iMaxCount <= _pArr->iCount)
{
// 재할당
Reallocate(_pArr);
}
// 데이터 추가
_pArr->pInt[_pArr->iCount++] = _iData;
/* 현재 인덱스에 데이터를 추가, 데이터를 추가한 뒤 후위 연산자로 인해
문장이 끝날때 iCount가 1증가 */
}
void ReleaseArr(tArr* _pArr)
{
free(_pArr->pInt);
_pArr->iCount = 0;
_pArr->iMaxCount = 0;
}
#include <stdio.h>
#include <iostream>
#include "Arr.h"
int main(void)
{
tArr arr = {};
InitArr(&arr); // 초기값 설정
for (int i = 0; i < 10; ++i) // 가변배열에 데이터 10개 넣기, (0 ~ 9)
{
PushBack(&arr, i); // 데이터 넣기 함수
}
for (int n = 0; n < 10; ++n)
{
printf("%d", arr.pInt[n]);
} // 데이터가 잘 들어갔음을 확인가능
ReleaseArr(&arr); // 메모리 해제, count, maxcount 초기화
return 0;
}