C++ std::vector 동적배열 대체


C++ std::vector 동적배열 대체


vector는 동적할당 해주는 기능을 가지고 있다.

그리고 우리가 동적할당 할때 우리가 직접 new해서 힙에 메모리 주소를 받아오고

사용이 끝나면 delete를 해줘야 한다는 불편함이 있다.


근데 vector는 이런 기능이 포함되어있고 자기가 알아서 delete를 해준다.


#include <iostream>
#include <vector>
using namespace std;
 
int main()
{
    int *my_arr = new int[5];
    delete[] my_arr;
    std::vector<int> arr2 = { 1,2,3,4,5 };
    cout << arr2.size() << endl;
 
    std::vector<int> arr3 = { 1,2,3, };
    cout << arr3.size() << endl;
    
    for (auto &n : arr3)
        cout << n << ' ';
    cout << endl;
    
    arr3.resize(10);
    for (auto &n : arr3)
        cout << n << ' ';
    cout << endl;
 
    arr3.resize(2);
    for (auto &n : arr3)
        cout << n << ' ';
    cout << endl;
 
 
    vector<int> arr = { 1,2,3,4,5 };
    cout << arr[0] << endl;
    cout << arr.at(0) << endl;
 
    return 0;
}


< 실행 결과 >



2행에서 보면 #include <vector>를 선언을 해줬다. vector을 사용하기 위해서는 vector 헤더파일을 include 해줘야 한다.

7행에서 우리가 일반적으로 하는 동적할당이다. 근데 일반적으로 동적할당을 하면 8행처럼 delete를 해줘야 하는 부담감이 있다.

그리고 delete 구문은 마지막에 하는데 delete 구문만 보고 이 동적 배열이 얼만큼의 배열이 되어 있는지 모른다는 점이 있다.


9행에서 보면 vector<"자료형"> "이름" 이렇게 선언을 해주면 된다.

vector은 컴파일러가 알아서 동적할당을 해준다.

vector의 장점은 우리가 직접 delete를 해줄 필요가 없고 블록 밖으로 나가거나 return을 해주게 되면 자동으로 알아서 delete를 해준다.

메모리가 새지 않는 장점이 있다.


10행에서 size() 사용하면 얼만큼의 동적할당이 되어 있는지가 나오게 된다.

19행에서 resize()를 사용했는데 이것은 동적 배열의 크기를 10만큼 재 정의 하겠다는 것이다.

출력을 해보면 나머지 배열에는 자동으로 0으로 초기화가 진행 된다.


그리고 다시 24행에서 resize(2)를 하게 되면 2개만 출력이 된다.

resize(2)를 하게 되면 메모리가 지워지게 되는 것이 아니다.


vector는 size와 capacity(용량) (이)가 있다.

capacity는 내부적으로 그 만큼 용량을 가지고 있다는 뜻이다.

size는 그만큼 용량을 사용한다 라는 뜻이다.


#include <iostream>
#include <vecotr>
using namespace std;
 
int main()
{
    std::vector<int> v{ 1,2,3 };
 
    v.resize(10);
 
    for (auto &e : v)
        cout << e << " ";
    cout << endl;
 
    cout << v.size() << " " << v.capacity() << endl;
    return 0;
}


7행에서 vector를 사용해 배열을 int형으로 동적할당 해줬다.

vector은 자기가 알아서 사이즈 맞게 해준다. (얼마나 편한가?)

9행에서 resize라고 배열을 10개로 늘려준다.

11~13행은 출력을 해주고

15행에서 현재 v의 size와 capacity를 출력해준다.



< 출력 결과 >



우리는 분명 1,2,3만 동적 할당을 해주고 size만 10으로 변경을 해줬다.

근데 resize를 하면 자동으로 나머지 값을 0으로 초기화 시켜준다.

그리고 size는 10으로 나오고 capacity도 10으로 나온다.

현재 사용하고 있는 용량은 10이고 용량이 10만큼 있다 라는 뜻으로 해석하면 되겟다.


#include <iostream>
#include <vector>
using namespace std;
 
int main()
{
    std::vector<int> v{ 1,2,3 };
 
    v.resize(10);
 
    for (auto &e : v)
        cout << e << " ";
    cout << endl;
 
    cout << v.size() << " " << v.capacity() << endl;
 
    v.resize(2);
    cout << v.size() << " " << v.capacity() << endl;
    return 0;
}


< 출력 결과 >



17행에서 사이즈를 2로 다시 설정했다.

그럼 현재 사용하는 메모리 공간은 2, 잡혀져 있는 공간은 10개 이다.


원래 int *v_ptr = new int[3]; 이렇게 하고 int형 3개 배열을 동적 할당을 해서 주소를 받아오고

size를 변경하려면 delete를 해주고 다시 new int[2]로 해서 변경을 해줘야 한다.

근데 vector은 new와 delete를 최대한 적게 사용 하려고(속도를 더 빠르게 하기 위해) delete를 안 해주고 그냥 컴파일러가 "2개만 사용할거야!" 라고 한 것이다.

그럼 v[2]를 해서 강제로 출력을 하면 runtime error가 난다.

그럼 v[2] 주소를 포인터로 받고 포인터로 출력해보면 값이 정상적으로 나온다.

즉, 더 작은 size로 할 때 컴퓨터가 2개만 있는 척을 하는 것이다.


이번에는 capacity를 100으로 설정해보자.


9행을 v.reserve(100); 으로 해서 다시 실행 해보자.


< 출력 결과 >



resize를 해줄 경우 0으로 자동 초기화가 되는 반면 reserve는 그냥 나온다.

그럼 reserve는 왜 하냐?


reserve를 하면 이미 공간을 잡아 놓았기 때문에 reserve를 사용 안하면 그때 그때마다 삭제하고 바꿔오고 기타 등등

더 속도가 느려지는 행동만 하게 된다. 그래서 reserve로 이미 공간을 확보하고 그때그때 마다 그냥 원소만 추가해주면 된다.

그렇기에 속도가 더 빨라지는 것이다.


vector 잘 사용하는 방법은 내부적으로 new와 delete를 적게 사용하도록 하는 것이다.

new와 delete는 속도가 느리기 때문에 되도록 이면 적게 사용하도록 하는 것이 좋다.


댓글

Designed by JB FACTORY