2012-04-30 3 views
1

나는 C++에서 std::list 클래스에 대해 알아 봤습니다. 궁금합니다. 간단히 말해서,리스트의 반복자가 작동하는 방식과 관련이있다. 다음 코드를 고려하십시오.표준 템플릿 라이브러리 목록 - 이중 연결 또는 순환 연결?

std::list<int> alist; 
alist.push_back(0); 
alist.push_back(1); 
alist.push_back(2); 

명백히 3 개의 정수 요소가있는 목록이 생성됩니다. 나는이 목록의 시작 반복자를 정의하고 다음과 같이 말, 첫 번째 요소에 포함 된 값을 출력하는 데 사용할 수 있습니다 : 나는 약간 이상한 찾을 무엇

std::list<int>::iterator iter = alist.begin(); 
std::cout << *iter << std::endl; // Prints "0" to stdout 

입니다 만약 내가 지금 감소 반복자는, 그것은 "주위 루프"와 목록의 마지막 요소를 가리키는 끝 :

--iter; 
std::cout << *iter << std::endl; // Prints "2" to stdout 

가정으로 이중 연결리스트로 구현 뭔가이 합리적인 행동인가? 목록이 순환으로 연결된 목록 인 경우에는 반복기와 비슷한 동작을 기대할 수 있지만 매우 이상합니다.

과거에 사용한 적이있는이 반복자 동작을 실제로 사용할 수 있습니까? 이 행동과 관련된 문제가 있습니까?

이 (그건 그렇고,이 GCC 4.7.0 (는 MinGW)가 발생합니다. 나는 다른 버전 또는 컴파일러와 함께 그것을 테스트하지 않았습니다.)

+0

그것은 나를 위해 -1218668059를 인쇄한다. http://ideone.com/3kpQf –

답변

10

begin 이상으로 반복자를 감소시키는 정의되지 않은 동작을 호출합니다. 당신이보고있는 행동은 우연 일 가능성이 큽니다. 실제로 다른 컴파일러에서 어떤 일이 일어나는지 확인하십시오. here.

이것을 확인하려면 GCC의 list 구현을 살펴보십시오. 당신은 보통 /usr/include/c++/4.x.y/bits/stl_list.h에 근원을 찾아 낼 수있다.

+0

고마워. 출처를 읽으면 일을 잘 정리하는 데 도움이되었습니다. (ideone에 대한 링크도 주셔서 감사합니다 - 이전에는 본 적이 없습니다!) – pmcs

+0

사실 저는 몇 가지 구현에서 원을 닫는 숨겨진 노드를 사용하는 것을 보았습니다. 그 * 가드 *를 사용하면 나머지 작업을보다 쉽게 ​​구현할 수 있습니다. 삽입/지우기는 목록의 시작/끝을 특수하게 할 필요가 없으며 단지'node-> last'와'node -> next' (그러나 그것들은 구현에서 호출 됨)이 유효한 * 객체 *를 참조한다는 것을 알고 있습니다. –

0

"2"는 상수 2 (alist.push_back(2);)라고 생각합니다. 프로그램이 매우 짧고 간단하다고 생각합니다. 맞습니까? 이것은 4.2.1 GCC에서 발견되었다

* 
    * Second, a %list conceptually represented as 
    * @code 
    * A <---> B <---> C <---> D 
    * @endcode 
    * is actually circular; a link exists between A and D. The %list 
    * class holds (as its only data member) a private list::iterator 
    * pointing to @e D, not to @e A! To get to the head of the %list, 
    * we start at the tail and move forward by one. When this member 

:

1

는 stl_list.h 보면, 나는이 댓글이났습니다. @Oli가 제공하는 응답은 gcc 4.2.1에서 구현 된 응답이므로 변경되지 않습니다. 나는 그 기능에 의지 할 것이다

+0

주석은 구현 측면에서 다소 오도 된 내용입니다. 해당 버전의 STL에서 목록을 구현하면 포인터 만 포함하는 노드 기본 유형과 노드 기반을 확장하고 실제 데이터를 포함하는 노드 구현이 정의됩니다. 이리스트는 루프를 닫는 노드 기반 인스턴스 (그리고 우연히'end() iterator)를 가지고있다.차이점을 만드는 세부 사항은 목록을 닫는 * link *가 데이터를 보유한 노드가 될 수 없거나 가장 간단한 루프를 수행하는 것이 불가능하다는 것입니다. –