2017-12-06 25 views
0

이의 문제 시각화 지원하는 도우미 클래스 만들어 보자 벡터의 크기가 증가하지 않습니다가 직접 오류가 발생하지 않습니다 예약 후 :: 성병에 벡터를 할당하지만

class C 
{ 
int ID = 0; 

public: 
C(const int newID) 
{ 
    ID = newID; 
} 

int getID() 
{ 
    return ID; 
} 
}; 

것은 당신이 빈 std::vector<C> 다음 예약을 만들 가정을

: 벡터의 인덱스 4에

std::vector<C> pack; 
pack.reserve(10); 
printf("pack has %i\n", pack.size()); //will print '0' 

지금, 당신은 C의 새로운 인스턴스를 할당 : 그것은 10 개 요소를 개최합니다

0 여기 이상으로 두 가지를 발견

1) 할당 컴파일러 (비주얼 스튜디오 2015 출시 모드)도 릴리스 모드에서 오류가 발생해서는 안?

2) 실제로 요소가 위치 4에 저장 되었기 때문에 벡터가 0이 아닌 크기 = 1을 갖지 않아야합니까?

+0

가능한 복제 [벡터 간의 선택 :: (크기 조정) 및 벡터 :: 보호구() (https://stackoverflow.com/ : pack.at(4) = C(57); 예외를

예 예외 :이다

질문/7397768/vector-choice-vectorsresize 및 vectorreserve) –

+0

@underscore_d 내 질문은 그 중 하나의 중복입니다 절대적으로 없습니다. 아니에요. '예비 '와'크기 조정'이하는 일을 꽤 잘 압니다. 내 질문은 '예약'이 호출 된 후 'at'의 동작에 관한 것입니다. – blipblop

+0

_ "내 질문은 'at'의 동작에 관한 것입니다. _ 긴 샷이 아닙니다. 어떻게 지구상에서'.at()'의 행동에 대해 그것이 한 번이라도 그 방법을 언급하지 않을 때 어떻게됩니까? '.at()'를 사용했다면, 프로그램은 정의되지 않은 동작을 생성하는 대신 명확한 오류를 신호로 보냅니다. 어쨌든, 당신의 질문은'.resize()'가 아닌'.reserve()'와''operator []' '를 포함한 특정 방법으로''를 증가시킬 수 있는지 묻는 것입니다. size()','.reserve()'이후의 할당되지 않은 점에 대한 색인 생성이 가능한지 여부를 지정합니다. '.at()'가 당신에게 말했던 것처럼 –

답변

1

정의되지 않은 동작은 여전히 ​​정의되지 않습니다. 이것을 우리가 객체의 벡터로 만들면 예기치 않은 동작이 더 분명하게 보입니다.

#include <iostream> 
#include <vector> 

struct Foo { 
    int data_ = 3; 
}; 

int main() { 
    std::vector<Foo> foos; 
    foos.reserve(10); 
    std::cout << foos[4].data_; // This probably doesn't output 3. 
} 

여기에서 우리는 실제로 개체를 할당하지 않았기 때문에 생성자가 실행되지 않았 음을 알 수 있습니다.

또 다른 예는 벡터가 실제로 할당을 시작하지 않은 공간을 사용하기 때문에 벡터가 해당 메모리를 다시 할당해야하는 경우 작성한 값은 복사되지 않습니다.

#include <iostream> 
#include <vector> 

int main() { 
    std::vector<int> foos; 
    foos.reserve(10); 
    foos[4] = 100; 
    foos.reserve(10000000); 
    std::cout << foos[4]; // Probably doesn't print 100. 
} 
+0

답장을 보내 주셔서 감사합니다. 그러나, 나는 그것이 나의 실제적인 예를 다룰 것이라고 생각하지 않는다. 코드에서, 당신은 ** fooo [4] = Foo()와 같은 새로운 Foo 객체를 할당하지 않습니다 **. 만약 그렇다면, 항상 '3'을 인쇄 할 것이고, 벡터는 0의 크기를 유지합니다. 컴파일러 없이도 오류가 발생합니다. – blipblop

1

짧은 답변 : operator[] 때문에 예외를 throw 할 이유가 없다

1) 당신이 통과 한 위치를 확인하기 위해 안됩니다. 디버그 모드에서는 그렇게 할 수 있지만 Release에서는 그렇지 않을 수 있습니다 (그렇지 않으면 성능이 저하됩니다). 릴리스 모드에서 컴파일러는 사용자가 제공 한 코드가 오류를 방지하고 모든 것을 수행하여 코드를 빠르게 작성하도록합니다.

지정된 위치 pos에있는 요소에 대한 참조를 반환합니다. 아니요 경계 검사가 수행됩니다. 당신은 단순히 당신이 아직 소유하지 않은 메모리를 액세스

http://en.cppreference.com/w/cpp/container/vector/operator_at

2

) ( reserve, 당신은 그것을 할 아무것도 정의되지 않은 동작입니다) resize 없습니다. 그러나, 당신은 vector에 요소를 추가 한 적이 없으며 버퍼를 수정했다고 생각하지 않습니다. 그리고 @Bill이 보여 주듯이 vector은 로컬 변경 사항을 복사하지 않고 버퍼를 변경할 수 있습니다.

편집 : 또한 vector::at 기능을 사용하면 경계 검사로 인해 예외가 발생할 수 있습니다. 가 https://ideone.com/sXnPzT