development

std :: vector :: resize () 대 std :: vector :: reserve ()

big-blog 2020. 11. 7. 10:48
반응형

std :: vector :: resize () 대 std :: vector :: reserve ()


이 게시물 의 댓글 섹션에는 std::vector::reserve()vs. 사용에 대한 스레드가 있습니다 std::vector::resize().

다음은 원래 코드입니다.

void MyClass::my_method()
{
    my_member.reserve(n_dim);
    for(int k = 0 ; k < n_dim ; k++ )
         my_member[k] = k ;
}

에서 요소를 작성 vector하는 것이 올바른 방법은 호출 std::vector::resize()이 아니라 라고 생각합니다 std::vector::reserve().

실제로 다음 테스트 코드는 VS2010 SP1의 디버그 빌드에서 "충돌"합니다.

#include <vector>

using namespace std;

int main()
{
    vector<int> v;
    v.reserve(10);
    v[5] = 2;

    return 0;
}

내가 맞습니까, 아니면 틀렸습니까? 그리고 VS2010 SP1이 맞습니까, 아니면 틀렸습니까?


이유에는 두 가지 방법이 있습니다.

std::vector::reserve 메모리를 할당하지만 벡터의 크기를 조정하지 않습니다. 벡터는 이전과 동일한 논리적 크기를 갖습니다.

std::vector::resize실제로 벡터의 크기를 수정하고 기본 상태의 객체로 모든 공간을 채 웁니다. 정수이면 모두 0이됩니다.

예약 후, 귀하의 경우에는 요소 5에 쓰기 위해 많은 push_backs가 필요합니다. 그렇게하지 않으려면 크기 조정을 사용해야합니다.


Jan Hudec의 답변 : vector :: resize () 및 vector :: reserve () 중에서 선택

두 기능은 매우 다른 일을합니다.

resize () 메서드 (그리고 생성자에 인수를 전달하는 것은 이와 동일 함)는 주어진 수의 요소를 벡터에 삽입합니다 (값을 지정하는 선택적 두 번째 인수가 있음). 그것은 size ()에 영향을 미칠 것이고, 반복은 그 모든 요소를 ​​지나갈 것이고, push_back은 그것들 뒤에 삽입 될 것이고, operator []를 사용하여 직접 접근 할 수 있습니다.

reserve () 메서드는 메모리 만 할당하지만 초기화되지 않은 상태로 둡니다. capacity ()에만 영향을 주지만 size ()는 변경되지 않습니다. 벡터에 아무것도 추가되지 않기 때문에 객체에 대한 값이 없습니다. 그런 다음 요소를 삽입하면 사전에 수행되었으므로 재 할당이 발생하지 않지만 그게 유일한 효과입니다.

그래서 그것은 당신이 원하는 것에 달려 있습니다. 1000 개의 기본 항목 배열을 원하면 resize ()를 사용하십시오. 1000 개의 항목을 삽입 할 것으로 예상하고 몇 가지 할당을 피하려면 reserve ()를 사용하십시오.

편집 : Blastfurnace의 의견으로 질문을 다시 읽고 귀하의 경우 정답은 수동으로 사전 할당하지 않는다는 것을 깨달았습니다. 필요에 따라 끝에 요소를 계속 삽입하십시오. 벡터는 필요에 따라 자동으로 재 할당되며 언급 된 수동 방식보다 더 효율적입니다. reserve ()가 의미있는 유일한 경우는 사전에 쉽게 사용할 수 있어야하는 총 크기를 합리적으로 정확하게 추정 한 경우입니다.

EDIT2 : 광고 질문 편집 : 초기 추정치가있는 경우 해당 추정치보다 reserve ()하고 충분하지 않은 것으로 판명되면 벡터가 그 일을하도록하십시오.


무엇을하고 싶은지에 따라 다릅니다. reserve요소를 추가 하지 않습니다vector . 을 변경하기 만하면 요소 capacity()추가 하면 재 할당되지 않습니다 (예 : 반복기 무효화). resize즉시 요소를 추가합니다. 나중에 요소를 추가하려면 ( insert(), push_back())을 사용하십시오 reserve. 나중에 요소에 액세스하려면 ( []또는 사용 at())을 사용하십시오 resize. 따라서 MyClass::my_method다음 중 하나가 될 수 있습니다.

void MyClass::my_method()
{
    my_member.clear();
    my_member.reserve( n_dim );
    for ( int k = 0; k < n_dim; ++ k ) {
        my_member.push_back( k );
    }
}

또는

void MyClass::my_method()
{
    my_member.resize( n_dim );
    for ( int k = 0; k < n_dim; ++ k ) {
        my_member[k] = k;
    }
}

당신이 선택한 것은 취향의 문제이지만, 당신이 인용 한 코드는 분명히 틀 렸습니다.


예, 맞습니다. Luchian은 방금 오타를 작성했으며 아마도 그의 실수를 깨닫기에는 커피가 부족한 것 같습니다.


벡터의 현재 크기보다 작은 숫자로 두 메서드가 호출되는 경우에 대한 논의가있을 것입니다.

Calling reserve() with a number smaller than the capacity will not affect the size or the capacity.

Calling resize() with a number smaller than current size the container will be reduced to that size effectively destroying the excess elements.

To sum up resize() will free up memory whereas reserve() will not.


resize actually changes the amount of elements in the vector, new items are default constructed if the resize causes the vector to grow.

vector<int> v;
v.resize(10);
auto size = v.size();

in this case size is 10.

reserve on the other hand only requests that the internal buffer be grown to the specified size but does not change the "size" of the array, only its buffer size is changed.

vector<int> v;
v.reserve(10);
auto size = v.size();

in this case size is still 0.

So to answer your question, yes you are right, even if you reserve enough space you are still accessing uninitialized memory with the index operator. With an int thats not so bad but in the case of a vector of classes you would be accessing objects which have not been constructed.

Bounds checking of compilers set to debug mode can obviously be confused by this behavior which may be why you are experiencing the crash.

참고URL : https://stackoverflow.com/questions/13029299/stdvectorresize-vs-stdvectorreserve

반응형