이번 글을 통해 배워갈 내용
- 2중배열을 동적으로 사용하기
프로그램 실행중에
동적으로 메모리 할당을 하는 경우
프로그램의 스택 메모리에서 할당되는게 아니고
힙에서 메모리할당을 하게 되는데
new 라는 키워드를 통해서 운영체제에 메모리를 요청하게 된다.
문제는 이러한 요청해서 받은 메모리는 관리를 해주지 못하는 경우
메모리 누수가 발생한다.
예를 들자면
2중 배열을 동적으로 선언한 다음
const int row = 3;
const int col = 3;
int** myArr = new int* [row];
for (int i = 0; i < row; i++)
{
myArr[i] = new int[col];
}
계속 반복해서 호출하면
처리되지 않은 예외 발생(0x7656B512, Project3.exe): Microsoft C++ 예외: std::bad_alloc, 메모리 위치 0x00D8FA84.
을 하게 되는데
스크린샷 왼쪽을 보면
메모리를 기하급수적으로 먹고 있는게 보인다.
이는 메모리를 다시 운영체제로 반납해주어야 하는데
반납을 안하고 가지고 있는 상태에서
변수에 새로운 메모리를 할당하기 때문에 문제가 발생하는 것이다.
물론 위의 경우에는
각 배열의 내부를 돌면서
const int row = 3;
const int col = 3;
int** myArr = new int* [row];
for (int i = 0; i < row; i++)
{
myArr[i] = new int[col];
}
if (myArr != nullptr)
{
for (int i = 0; i < row; i++)
{
if (myArr[i] != nullptr)
{
delete[] myArr[i];
}
}
delete[] myArr;
}
메모리 할당을 해제해주면
메모리 누수를 방지 할 수 있다.
위에 스크린샷 처럼
메모리상에 누수가 없는것 같이 보인다.
하지만
매번 이렇게 new를 사용해서 관리하는것도
귀찮은 일이다.
물론 정적과 자동 방법을 이용해서 메모리를 할당하는 경우도 있지만.
프로그램 실행중에 이중 배열을 생성하고자 하는 이에게는
고민이 되는 부분일 것이다.
그래서 검색을 해보았고 아래 정보를 발견 했다.
https://stackoverflow.com/questions/58631105/dynamic-2d-array-without-using-new
스택오버플로우에서 말씀하시길
new가 C++ 스탠다드에서는 동적 객체를 만드는 유일한 방법이다.
(malloc 이랑 free 도 있지만 그건 비슷한 개념이기 때문에 new가 더 편함)
하지만 STL 라이브러리를 쓰게 되면 new 함수가 내부에 포함되기 떄문에 문제를 해결할 수 있다.
2d 배열을 선언할때 많이 쓰는 방법은 std::vector를 쓰는 것이다.
#include <vector> 을 상단에 추가하고
std::vector<std::vector<타입>> 배열명칭;
으로
아래와 같이
사용하게 되면
const int row = 3;
const int col = 3;
std::vector<std::vector<int>> myVec;
for (int i = 0; i < row; i++)
{
std::vector<int> tempVec;
for (int j = 0; j < col; j++)
{
tempVec.push_back(0);
}
myVec.push_back(tempVec);
}
메모리를 자동으로 할당하고 해제 해주는 것을 알수있다.
직접 쓰게 된다면
아래와 같이
0으로 초기화 후에
쓰는 것도 좋을것 같다.
const int row = 3;
const int col = 3;
std::vector<std::vector<int>> myVec;
for (int i = 0; i < row; i++)
{
std::vector<int> tempVec;
for (int j = 0; j < col; j++)
{
tempVec.push_back(0);
}
myVec.push_back(tempVec);
}
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
std::cout<<myVec[i][j];
}
std::cout << "\n";
}
myVec[2][2] = 1;
아니면
가변할 필요 없이
#include <array>을 사용해서
std::array를 쓰더라도
자동관리를 해준다.
const int row = 3;
const int col = 3;
std::array<std::array<int, col>, row> my2DArr;
std::array<int, col> tempArr;
tempArr.fill(0);
my2DArr.fill(tempArr);
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
std::cout << my2DArr[i][j];
}
std::cout << "\n";
}
오늘은 std를 이용해서 여러 2d 배열을 만들어 봤습니다.
오늘도 즐거운 코딩하시길 바랍니다 ~ :)
참조 및 인용
https://docs.microsoft.com/en-us/cpp/cpp/new-and-delete-operators?view=msvc-160
C++ Primer
https://codemasterkimc.tistory.com/35
https://codemasterkimc.tistory.com/50
'C++ > C++ 기타' 카테고리의 다른 글
visual studio 2019에서 줄맞춤 단축키, 줄정렬 단축키 (0) | 2021.10.16 |
---|---|
C++에서 Floating 값을 0과 비교하는 방법 (0) | 2021.10.07 |
C++ 타입캐스팅에 대한 생각과 팁 (0) | 2021.08.20 |
C++에서 string을 int, uint혹은 long으로 변경하기 (1) | 2021.07.21 |
C++에서 new로 동적 메모리 할당 후 null값 체크를 해야 할까요? (1) | 2021.07.20 |