2016-06-04 3 views
3

while 루프를 사용하여 구조체의 (정렬 된!) 벡터를 통과하는 짧은 코드를 작성하고 해당 가격을 기반으로 새 요소를 삽입합니다디버그 어설 션이 실패했습니다. Visual Studio 2015 : 반복자 벡터가 아닌 벡터 반복자

g++과 Sublime Text 3을 사용하면 모든 것이 작동하지만 (이 질문의 끝에 출력 됨) Visual Studio 2015를 사용하면 오류가 발생합니다. Debug Assertion Failed! ... Expression: vector iterator not dereferencable.이 오류는 새 요소를 struc newEl = {5, 2.0}으로 변경하는 경우 기존 요소의 끝에 새 요소를 연결해야하는 경우에만 나타납니다 (VS와 g++ 모두 제대로 작동 함).

코드는 다음과 같습니다

#include <iostream> 
#include <vector> 

struct struc { 
    int num; 
    double price; 
}; 

int main() { 
    std::vector<struc> v = { { 1, 1.5 },{ 2, 1.6 },{ 3, 2 },{ 4, 2.6 } }; 
    struc newEl = { 5, 2.7 }; 

    std::vector<struc>::iterator it = v.begin(); 

    while (((*it).price <= newEl.price) && (it < v.end())) { 
     it++; 
    } 

    v.insert(it, newEl); 

    for (struc vec : v) { 
     std::cout << vec.num << ", " << vec.price << std::endl; 
    } 

    std::cout << "Finished"; 
    return 0; 
} 

출력이되어야한다 (그리고 g++의 경우와 ST에) :

1, 1.5 
2, 1.6 
3, 2 
4, 2.6 
5, 2.7 
Finished 

이제 내 질문에, 무슨 VS에서 오류가 발생한다 VS에서 작동하도록 변경하려면 무엇이 필요합니까?

대단히 감사합니다!

답변

6
while (((*it).price <= newEl.price) && (it < v.end())) { 

당신은 당신이 반복자 역 참조 전에 마지막 에 있는지 확인하고 값을 확인해야합니다 : 당신이 기본적으로 보장되어 그렇지 않으면

while ((it!=v.end()) && (it->price <= newEl.price)) { 

을 당신입니다 end 반복자, 역 참조 정확하게 당신이 피하려고하는 것.

(대부분의 유형의 반복기에서는 <을 사용할 수 없으므로 !=으로 루프를 검사하는 것이 더 일반적입니다.)

&& "단락"이므로 첫 번째 조건이 false 인 경우 두 번째 조건도 확인되지 않습니다. 이것은 언어에 의해 보장됩니다 (일부 바보가 operator&&을 오버로드하지 않는 한, 그것은 그렇게 나쁜 생각이기 때문에 고맙게도 드뭅니다). 그래서 내 버전이 안전합니다.

이제 실수로 Undefined Behaviour이 발생합니다. 오류가 발생했습니다. 언어는 심지어 당신을 도우려고하지 않으며, 어떤 일이 일어날 수 있습니다. 프로그램이 중단되거나 정상적으로 작동하거나 다른 시간대에 작동하거나 노트북이 분홍색 기린으로 바뀔 수 있습니다. C++ 거래는 빠르게 진행되는 것에 대해 당신에게 친절합니다.

디버깅 모드에서 마이크로 소프트 구현은 항상 여기에서 실수를 저지르고있는 checked iterators을 가지고 있음을 알고 있습니다. 릴리스 모드에서는 이러한 일이 발생하지 않습니다.

나는 그것을 사용하지 않았지만, this answer에 따르면, GCC는 비슷한 것을 가지고있다.


(여담으로, 나는 정말 나쁜 관행으로 std::endl의 사용을 고려한다. Here's why. 어떤 사람들은 그 날에 동의하지 않는다. 그것에 대해 알아보고 자신의 결정을, 나는 가정합니다.)

+0

그것으로 문제가 해결됩니다. 바보 증명에 대해서도 설명해 주셔서 감사합니다 (이해할 수 있음).왜 ST +'g ++'가 VS와는 반대로 작동하는지 알고 있습니까? – David

+0

@David 나는 내 대답을 약간 마무리했다. – BoBTFish

+0

Wonderful, 나는 당신의 블로그를 읽고'std :: endl'로 당신의 발언을 만났습니다. 나는 그것을 염두에 두겠다! 철저한 답변을 해주셔서 다시 한 번 감사드립니다! – David