programing

std::벡터 대 표준::C++의 배열

starjava 2023. 5. 22. 20:06
반응형

std::벡터 대 표준::C++의 배열

a 사이의 차이점은 무엇입니까?std::vector 리고그.std::array로? C++로?어떤 경우에 어떤 것이 다른 것보다 더 선호되어야 합니까?각각의 장단점은 무엇입니까?제 교과서는 그것들이 어떻게 같은지 나열하는 것뿐입니다.

std::vector요소를1 추가하거나 제거할 경우 자동으로 증가 및 축소되는 동적 배열을 힙에 저장하는 템플릿 클래스입니다.모든 후크를 제공합니다(begin(),end()반복기 등)를 사용하여 STL의 나머지 부분에서 정상적으로 작동합니다.또한 벡터 중간에 요소를 삽입하는 것과 같이 일반 배열에서 번거로운 작업을 수행할 수 있는 몇 가지 유용한 방법이 있습니다(다음 요소를 뒤로 이동하는 모든 작업을 처리합니다).

힙에 할당된 메모리에 요소를 저장하기 때문에 정적 어레이와 관련하여 약간의 오버헤드가 있습니다.

std::array정적 크기의 배열을 캡슐화하는 템플릿 클래스로, 개체 자체 내부에 저장됩니다. 즉, 스택에서 클래스를 인스턴스화하면 어레이 자체가 스택에 있게 됩니다.컴파일 시 크기를 알아야 하며(템플릿 매개 변수로 전달됨) 크기를 늘리거나 줄일 수 없습니다.

▁than▁보다 더 제한적입니다.std::vector그러나 실제로는 대부분 C 스타일 어레이 주변의 가벼운 포장지이기 때문에 특히 작은 크기의 경우 더 효율적입니다. 그나포인암변비묵어다있의 STL 에 더std::vector그리고 다른 컨테이너들을 사용하여 STL 알고리즘과 함께 쉽게 사용할 수 있습니다.어쨌든, 고정된 크기의 매우 제한적인 경우보다 훨씬 덜 유연합니다.std::vector.

에대 위해를개에 대한 .std::array 기사를 보세요; 빠른 소개를 위해.std::vector가능한 작업에 대한 설명서를 참조할 수 있습니다.


  1. 사실, 저는 표준에서 그것들이 다양한 작업의 최대 복잡성 측면에서 설명된다고 생각합니다(예: 일정한 시간에 랜덤 액세스, 선형 시간에 모든 요소에 대한 반복, 일정한 상각 시간에 마지막에 요소 추가 및 제거 등). 하지만 AFAIK는 동적 어레이를 사용하는 것 외에 이러한 요구 사항을 충족하는 다른 방법이 없습니다.@Lucretiel이 언급한 바와 같이, 이 표준은 실제로 요소들이 연속적으로 저장되어야 하므로, 관련 할당자가 배치하는 곳에 저장된 동적 배열입니다.

@MatteoItalia의 요점을 강조하기 위해 효율성 차이는 데이터가 저장되는 위치입니다. 메모리 " " " " " "와 함께 합니다.vector를 할당하기 하며, 들 수 에서는 메모리를 할당하기 위해 시스템에 대한 호출이 필요하며, 사이클을 계산하는 경우 비용이 많이 들 수 있습니다.스택 메모리(가능한 경우)array메모리는 단순히 스택 포인터를 조정하는 것만으로 할당되고 함수에 대한 엔트리에서 한 번만 수행되기 때문에 시간적으로 사실상 "제로 스레드"입니다.또한 스택은 메모리 조각화를 방지합니다. 확히실,std::array항상 스택에 있는 것은 아닙니다. 할당 위치에 따라 다르지만 여전히 벡터에 비해 힙에서 메모리 할당이 하나 적습니다.만약 당신이 가지고 있다면.

  • 작은 "어레이"(100개 이하의 요소가 말합니다) - (일반적인 스택은 약 8MB이므로 코드가 재귀적인 경우 스택에 몇 KB 이하를 할당하지 마십시오.)
  • 크기는 고정될 것입니다.
  • 수명이 함수 범위(또는 상위 클래스와 수명이 동일한 멤버 값)에 속합니다.
  • 당신은 사이클을 세고 있습니다.

반시를사다니합용드▁a다니▁defin▁useitely를 사용합니다.std::array벡터 위에이러한 요구 사항 중 하나라도 사실이 아닌 경우 다음을 사용합니다.std::vector.

빠른 참조를 위해 위의 논의를 표에 요약합니다.

C-스타일 배열 std::array std::삭제
크기 고정/정적 고정/정적 역학
메모리 효율성 효율성 향상 효율성 향상
할당 시 를 두 로 늘릴 수
복사 요소를 합니다.
사용하거나 ::copy를 사용합니다.
직접 복사: a2 = a1; 직접 복사: v2 = v1;
함수로 전달 포인터로 전달되었습니다.
불가 (기능상 사용 불가)
전달된 값 된 값 달된 값
기능에서 가능한 사용 가능한 크기)
크기 크기(a1) / 크기(a1[0]) a.size () v1.size()
유스케이스 빠른 액세스 및 시간
자주 필요하지 않은 삽입/삽입
과 동일하지만 어동일지만하기와레존이▁same만▁but.
더 안전하고 쉽게 통과하고 복사할 수 있습니다.
추가를 자주 하거나
.

다차원 배열을 사용하는 것을 고려하고 있다면 다음과 같은 추가적인 차이점이 있습니다.std::array그리고.std::vectorstd::arrayC 스타일 배열과 마찬가지로 모든 차원의 요소가 메모리에 패킹됩니다.std::vector모든 치수로 포장되지 않습니다.

다음과 같은 선언이 있을 경우:

int cConc[3][5];
std::array<std::array<int, 5>, 3> aConc;
int **ptrConc; // initialized to [3][5] via new and destructed via delete
std::vector<std::vector<int>> vConc; // initialized to [3][5]

배열 C-style 배열(cConc)의 첫 번째 입니다.std::array의 각 요소에 배열을 할 수 있습니다 (aConc) 의을 각 1여 전 체 배 반 을 복 있 수 니 습 다 할 열 는 하 가 앞 추 요 소 에 ▁( 있 다 니 습 ▁by ▁can 수 a ( a ▁through ▁be erated conc ▁adding ▁it ▁element ▁to ▁1그것들은 빽빽이 들어차 있습니다.

벡터 배열(vConc) 또는 포인터 배열(ptrConc)의 첫 번째 요소에 대한 포인터는 처음 5개의 요소(이 경우)를 통해서만 반복될 수 있으며, 다음 벡터에 대한 오버헤드는 12바이트입니다.

즉, 다음을 의미합니다.std::vector<std::vector<int>>가 레이로초로 [3][1000]는 " 이는메로서모에리것것훨다작입어레니을씬보"로 초기화된 가 훨씬 입니다.[1000][3] 그리고 둘 다 , 그고둘보서에보다 클 입니다.std::array어느 쪽이든 할당됩니다.

는 메모리 오버헤드를 하지 않고 단순히 벡터(수 벡터( 포인터) 할 수 합니다.std::arrayOpenGL을 사용하여 해결할 수 있습니다.

std::vector<T> 명령어:

  • ...내장 어레이가 허용하는 작업(기존 요소 읽기 및 쓰기)만 수행한다고 가정할 때 내장 어레이를 사용하는 것만큼 빠릅니다.

  • ...새 요소를 삽입하면 크기가 자동으로 조정됩니다.

  • ...벡터의 시작 부분이나 중간 부분에 새 요소를 삽입하여 나머지 요소를 자동으로 "위쪽으로" 삽입할 수 있습니다(그게 말이 됩니까?).이 기능을 사용하면 어디서든 요소를 제거할 수 있습니다.std::vector나머지 요소도 자동으로 아래로 이동합니다.

  • ...를 확인 할 수 범위 확인 읽기를 수행할 수 있습니다.at()할 수 .)[]이 검사를 수행하지 않으려는 경우).

있다 두 개 사용 시 주의해야 할 세 가지 사항std::vector<T>:

  1. 기본 포인터에 대한 신뢰할 수 있는 액세스 권한이 없습니다. 는 배열의 주소를 요구하는 타사 함수를 처리하는 경우 문제가 될 수 있습니다.

  2. std::vector<bool>수업은 바보같습니다.배열이 아닌 축약된 비트 필드로 구현됩니다.다음의 배열을 원하는 경우 피하십시오.bools!

  3. 사용 중,std::vector<T>s는 같은 수의 요소를 가진 C++ 배열보다 약간 더 클 것입니다.이것은 그들이 그들의 현재 크기와 같은 작은 양의 다른 정보들을 추적할 필요가 있기 때문이고, 그리고 항상.std::vector<T>크기를 조정하면 필요한 공간보다 더 많은 공간을 확보할 수 있습니다.이는 새 요소를 삽입할 때마다 크기를 조정해야 하는 것을 방지하기 위한 것입니다.이 동작은 사용자 지정을 제공하여 변경할 수 있습니다.allocator하지만 그럴 필요성을 전혀 느끼지 못했어요!


편집: 질문에 대한 Zud의 답변을 읽고 다음과 같이 추가해야 한다고 느꼈습니다.

std::array<T>클래스가 C++ 배열과 같지 않습니다. std::array<T>는 클래스의 사용자로부터 포인터를 숨기는 것이 주된 목적인 C++ 어레이 주변의 매우 얇은 래퍼입니다(C++에서는 어레이가 암시적으로 포인터로 캐스팅되어 종종 디스 효과를 발생시킵니다).std::array<T>클래스는 크기(길이)도 저장하므로 매우 유용할 수 있습니다.

벡터는 컨테이너 클래스이고 어레이는 할당된 메모리입니다.

언급URL : https://stackoverflow.com/questions/4424579/stdvector-versus-stdarray-in-c

반응형