본문 바로가기
공부

[C++] 벡터(vector)와 벡터의 멤버함수 에 대하여

by MY블로그 2022. 11. 8.
벡터 (vector) 

[당일 수업 내용 中]

힙공간에 저장되고 생성과 해제가 자동으로 이루어진다.
동적할당이이루어지면서 증가되면 스스로 저장가능한 공간에 이동하며 공간을 늘린다.
공간이 이동이 여러번이루어지면 컴퓨터가 느려진다.

배열의 장점 : 순차적이고 연속적이다 때문에 주소연산이 가능하다.
배열의 단점 : 크기가 고정 되어 있다.

벡터는 배열과 유사하게 사용이 가능하며 배열의 단점인 크기고정을 해결할수 있다.

벡터를 생성하게되면 이는 동적할당이가능한것이며 heap(힙) 메모리 영역에 생성이 된다.

할당과 해제는 자동적으로 이루어지기때문에 별도의 작업을 할 필요가 없다.

 

벡터의 사용 방법은 <vector> 헤더파일을 추가 해야 한다.

ex ) #include <vector>

vector의 선언 방법 - " vector<데이터타입(ex.int float...)> [변수이름] " 으로 선언한다.

ex ) vector<int> name;


vector의 생성자와 연산자 (예시는 int 사용)

vector<int> name;  int형의 비어있는 vector name를 생성 한다.
vector<int> name(5); 기본값이 (0)으로 초기화된 5개의 원소를 가지는 vector name를 생성 한다.
vector<int> name(5, 2); (2)으로 초기화된 5개의 원소를 가지는 vector name를 생성 한다.
vector<int> name1(5, 2);
vector<int> name2(v1);
name2는 name1 vector를 복사해서 생성됩니다.
vector<int> name1; , vector<int> name2; 가 있고, 내부에 인자들이 있다고 가정 하였을때
연산자 : [ == ] [ != ] [ < ] [ > ] [ <= ] [ >= ] 를 사용하여 비교가 가능하다.

벡터(vector)의 멤버 함수 ( vector<int> v; 라고 가정, 참조 == 해당 데이터를 리턴 한다는 뜻)
참조 : https://blockdmask.tistory.com/70

name.insert(2, 3, 4);

- 2번째 위치에 3개의 4값을 삽입한다. (삽입지점 뒤에있던 위치들은 뒤로 밀려남)

 

name.insert(2, 3);

- 2번째 위치에 3의 값을 삽입한다. 삽입한 곳의 iterator를 반환한다.


name.erase(iter);

- iter 가 가리키는 원소를 제거한다.

- size만 줄어들고 할당된 메모리인 capacity는 그대로 남아 있는다.

- erase는 파라미터 하나를 받았을경우 해당 파라미터만 제거가된다.

 예외적으로 두개의 파라미터 v.erase(start, end);일경우 start이상~end미만이 제거된다.

 

예시로 아래부분을 vector v; 로 가정 하였을때

v.erase(start, end);

  start(제거) (제거) (제거) (제거) end  

위처럼 start를 포함하여 end바로 앞까지 제거가 이루어진다.

 


name.begin();

- 첫번째(시작점) 원소를 가리킨다. (*iterator와 사용) *iterator - 반복자.

ex) vector<int>name = {1, 2, 3, 4, 5, 6}; // *name. begin(); = 1 을출력한다.

 

name.end();

- 마지막(끝) 원소의 "다음"부분(back+1)을 가리킨다. (iterator와 사용)

ex) vector<int>name = {1, 2, 3, 4, 5, 6}; // *name. end(); = 6이출력되지않고 오류가된다. 6의다음은 x.

 

참조 : https://terms.naver.com/entry.naver?docId=3532971&cid=58528&categoryId=58528


name.fornt();

- 첫 번째의 원소를 참조 한다. 참조한다 => 해당 데이터를 리턴 한다.

ex) vector<int>name = {1, 2, 3, 4, 5, 6}; // *name. front(); = 1 을출력한다.

 

name.back();

- 마지막의 원소를 참조 한다. 참조한다 => 해당 데이터를 리턴 한다.

ex) vector<int>name = {1, 2, 3, 4, 5, 6}; // *name. back(); = 6 을출력한다. (위의 end(); 와다르게 끝부분이 확실히 출력됨)


name.size();

- 원소의 갯수를 리턴한다.

 

name.resize(n);

- 크기를 n으로 변경한다.

- 크기가 더 커졌을 경우 default값인 0으로 초기화 한다.

ex) 기존의 벡터 사이즈가 5보다작고 name. resize(5); =  0 0 0 0 0 

name.resize(n, 3);

- 크기를 n으로 변경한다.

- 크기가 더 커졌을 경우 인자의 값을 3으로 초기화 한다.

ex) name. resize(5) 상태에서 name. resize(10, 7); = 7 7 7 7 7 7 7 7 7 7 이 된다.

 

name.reserve(n);

- 내부 버퍼 크기를 n으로 지정한다. (출력시켜보았을떄 벡터의 크기보다 작으면 안되고 보다큰수로만 지정되는듯)

 

name.capacity();

- 오늘 수업에서 배우고 예제로 보기까지 했다. 버퍼의 기능.

- 버퍼란 벡터의 크기(원소갯수)가 자주 늘어나 위치변동이 잦은 경우 미리 여분의 크기를 확보해두는것이다.

- 최초 몇번의 vector크기가 변동할때는 여분공간의 갯수가 일정하다 여러번 늘어나면 자동적으로 추가공간을 확보한다.

- 출력을 예시로 봤을때 추가여분의 할당크기는 일정한 크기가 늘어나는 것을 확인 하였다.

- 조사를 하다보니 추가여분이 아주커질경우 여분의 크기가 기하급수적으로(벡터의 약 1.5배?) 늘어나는 케이스도 보았다.


name.clear();

- 모든 원소를 제거 한다.

- 원소만 제거되며 할당되어있는 메모리는 남아있다.(빈공간)

- size만 줄어들며 capacity(버퍼,여분공간)는 그대로 남아있다.

(주의 . v.erase()와 혼동하지않기. 클리어는 말그대로 전부깔끔하게 초기화하는것이며 erase는 지정부분 제거이다)

 


name.shrink_to_fit();

- C++11 에서 새로 도입된 함수 이다.

-기존에 swap()밖에 없었던 연속된 메모리를 가진 컨테이너의 capacity를 줄여주는 함수이다.

- vector(int) v;로 현재 size에 맞게 capacity를 줄이는데 사용할 수 있다.

  (주의. resize / clear / erase 의 기능은 내부원소만 지울뿐. 할당된 메모리를 지우지는 않는다는점 참고) 

- 함수의 내부적인 동작은 기존의 swap의 형태처럼 메모리 재할당과 동일하다.

- shrink_to_fit() 은 기존의 벡터가 가리키고 있던 메모리와는 다른 현재 size만큼의 크기를 가진 새로운 메모리를 할당받아    서 기존의 메모리의 모든 원소를 새로운 메모리에 복사 생성화는 과정이 있다.

- 위의 과정인 기존의 데이터가 크면 클수록 시간비용이 많이 소모 될수가 있다는 주의점이 있다.

 

- 개인적으로 내린 결론 : 위의 capacity의 자동기능이 편리하기는하나 기하급수적으로 크게 잡히는 경우 사용하지않고 대기상태의 용량의 낭비가 있을 수 있기때문에 shrink_to_fit()의 기능이 구현된것이 아닌가? 싶다.

다만 해당기능은 본래 차지하고 있는 vector의 용량이 일정 크기까지만 효율적이고 크기가 클수록(capacity의 크기도 커지기 때문에) 해당 기능에 필요한 시간과 기기의높은 성능이 요구될 것으로 생각 된다.

크기가 크면 오히려 더 필요하지 않은건가? 생각했으나 swap처럼 새로운 빈공간생성> 대입 > 기존의 큰공간 삭제 의 과정처럼 새롭게 큰공간을 마련하고 지우는 작업이 효율적이지는 않다고한다..... 

'공부' 카테고리의 다른 글

22.11.09 복습  (0) 2022.11.09
복습 - 행렬 회전 과제  (0) 2022.11.09
[C++] STL 에 대하여  (0) 2022.11.08
복습2 - 연산자  (0) 2022.11.08
복습1 - 정수와 실수  (0) 2022.11.08

댓글