#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> VectorName;
VectorName.push_back(2);
VectorName.push_back(3);
cout << VectorName[1] << endl;
VectorName.pop_back();
cout << VectorName[1] << endl;
}
내 이해에서 pop_back ()은 벡터의 마지막 인덱스를 팝한다고 가정하고 컴파일이 어떻게 될 것이라고 예상했는지는 오류를 발생시키는 것이 었습니다. 그러나 콘솔의 출력은 다음과 같이 명시되었습니다.
3 3
누군가가이 프로그램의 컴파일이 성공한 이유를 설명 할 수 있습니까?
감사합니다.
vector<>::operator[]()
벡터의 크기를 확인하지 않으므로 코드가 정의되지 않은 동작을 생성합니다.
특정 경우에 벡터의 크기 (벡터의 항목 수)는 줄어들지 만 . 을 호출 할 때 용량 (기본 배열의 크기 )은 줄어들지 않습니다 pop_back()
. 이것은 두 번째 VectorName[1]
가 사용되지 않았지만 기존 메모리를 가리킴을 의미합니다 . 예를 들어 용량과 크기를 확인하기 위해 예제를 약간 편집하면 :
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> VectorName;
VectorName.push_back(2); // |[2]|
VectorName.push_back(3); // |[2, 3]|
VectorName.pop_back(); // |[2], 3|
cout << VectorName.size() << endl;
cout << VectorName.capacity() << endl;
}
출력은 다음과 같습니다.
1
2
여기에서 작동하는 예를 볼 수 있습니다. http://coliru.stacked-crooked.com/a/70d5141bdc375b48
보시다시피 벡터의 크기는 정확하지만 (1 개 항목)에 대한 호출 VectorName.pop_back()
은 용량을 줄이지 않으므로 3
벡터에 여전히 존재하지만 액세스 할 수 없습니다.
을 호출 한 후 두 번째 항목에 액세스하면 VectorName.pop_back()
정의되지 않은 동작이 발생합니다. 귀하의 경우 3
에는를 얻지 만 다른 컴파일러, 아키텍처 또는 기계를 사용하여 응용 프로그램을 컴파일하면 응용 프로그램이 충돌하거나 더 나빠질 수 있습니다!
사용 vector<int>::at()
대신, vector<int>::operator[]()
발생했을 std::out_of_range
충돌로 프로그램을 일으키는 예외. 이는 at()
함수가 벡터의 크기를 확인하고 벡터의 경계를 벗어난 위치에 액세스하려고하면 예외를 발생시키기 때문입니다. 즉, at()
벡터 액세스를 확인하기 위해 함수에 의존하지 말고 size()
를 호출하기 전에 벡터 를 확인하는 것이 VectorName[1]
좋습니다.
예를 들어 코드를 다시 약간 수정하면 at()
함수를 사용할 때 어떤 일이 발생하는지 확인할 수 있습니다 .
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector<int> VectorName;
VectorName.push_back(2);
VectorName.push_back(3);
cout << VectorName.at(1) << endl;
VectorName.pop_back();
cout << VectorName.at(1) << endl;
return 0;
}
삼
'std :: out_of_range'의 인스턴스를 던진 후 종료가 호출됩니다.
what () : vector :: _ M_range_check : __n (1)> = this-> size () (1)
bash : 줄 7 : 4793 중단됨 (코어 덤프 됨) ./a.out
라이브 예 : http://coliru.stacked-crooked.com/a/8226be85196f54fe
"컴파일 오류"에 대한 추가 사항. 컴파일러는 사용자가 벡터에 액세스하기 전에 벡터의 크기를 확인하지 않으므로 컴파일러는 오류나 경고없이 코드를 즐겁게 컴파일합니다. 코드에 대한 경계 검사를 수행하는 것은 개발자에게 달려 있습니다.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다