2015-01-03 2 views
1

다음 노드/이전 노드에 대한 값 + 2 포인터를 보유하는 node라는 간단한 구조체가 있습니다.사용자 정의 유형에 std :: ptrdiff_t 사용

template <class T> 
struct node { 

    node<T> *prev = NULL; 
    node<T> *next = NULL; 
    T data;   
}; 

여기에 새로운 노드를 추가하는 기능이 있습니다.

void push_back(T val) {   

    node<T> *n = new node<T>; // create node to hold val 
    n->data = val;    // set node data with val 

    if (node_count == 0) {  

     begins = n;    // begins points to first node   
    } 
    else{ 

     ends->next = n;   // set next in ends 
     n->prev = ends;   // set previous    
    } 

    ends = n;     // update ends 
    node_count++;    // update list size 
}          

주에서는 각각 고유 한 int 값을 보유한 100 개의 링크 된 노드를 만듭니다. 내가 경우,

std::ptrdiff_t node_sum = ends - begins; 

어떻게 든 node_sum == 528 : 포인터 연산을 적용하려고 할 때 문제가 시작

node<T> *begins; 
node<T> *ends; 

: 여기

for (int i = 0; i != 100; i++){ push_back(i); } 

첫 번째/마지막 노드에 대한 포인터 x32를 컴파일 한 다음 node_sum == 781.

node_sum이 100이 아닌 이유는 무엇입니까?

+0

이 코드가 컴파일됩니까? 'push_back' 함수에는 당신이 전역 적으로 만들지 않는 한'begin'과'end'도 없습니다. – Ankur

+1

목록에 별도의 노드를 배치하는 것에 대한 보장은 없습니다. 제 1 노드는 제 2 노드 이전에 위치하고 제 3 노드 이후에 위치 할 수있다. 'ptrdiff_t' 타입은 두 개의 포인터를 하나의 배열 (또는 배열의 끝을 넘어서는 하나의 요소)의 위치를 ​​가리키는 2 개의 포인터를 의미하는 보장 된 연속 메모리로 만드는 데 사용됩니다. 다른 것은 정의되지 않은 행동으로 이어집니다. 어떤 결과라도 가능하며 모두 정확합니다. –

+0

@Shan : 게시 된 코드는 컴파일되지 않지만 소스 코드에서는 눈에 쉽게 띄울 수 있도록 관련 부분을 해킹했습니다. – tuk

답변

3

할당을 서로 옆에 배치하더라도 할당이 연속적 일 필요는 없음을 기억하십시오.

즉, 예를 들어

begin = new node<T>; 
end = new node<T>; 

beginend가 서로 옆에있을 것입니다 보장 아니에요.

배열과 같은 메모리 영역을 가리키는 포인터에 대해서만 포인터 연산을 사용할 수 있습니다. 그렇지 않으면 정의되지 않은 동작이 발생합니다.

4

노드가 배열의 일부가 아닙니다. 그것들은 각각 메모리 할당자가 그들을 찾을 수있는 모든 위치에 별도로 할당됩니다. 당신은 그것들을 빼거나 어떤 특별한 가치를 기대할 수 없습니다. 사실 그렇게하는 것은 정의되지 않은 동작입니다. 연결된 목록의 노드 사이의 거리를 계산하려면 다음 또는 이전 포인터를 따라 반복해야합니다.

관련 문제