2012-03-26 3 views
0

링크 된 목록에 대한 코드를 작성하려고하지만 노드를 추가하려고하면 코드가 add() 함수의 while 루프 바로 다음 행에 멈추게됩니다. 액세스 위반 오류. 뭐가 문제 야?액세스 위반 - 위치에 쓸 수 없음

#include<iostream> 

template <class T> 
class linkedlist 
{ 
    struct node 
    { 
     T data; 
     node *lp; 
    }*p; 
public: 
    linkedlist(); 
    void add(T t); 
}; 

template<class T> 
void linkedlist<T>::add(T t) 
{ 
    node *r,*q; 
    r = q = p; 

    while(p!= NULL) 
    { 
     q = p; 
     p = p->lp; 
    } 

    q->lp = new node; 
    q->lp->data = t; 
    p = r; 
} 

template<class T> 
linkedlist<T>::linkedlist() 
{ 
    p = NULL; 
} 

int main() 
{ 
    linkedlist<int> l1; 
    l1.add(3); 
} 

답변

1

당신은 (q를 통해) 다음 add에서 역 참조하려고, 생성자에서 NULLp를 초기화 :

r = q = p; 
// the while loop will not be executed as p == NULL 
q->lp = new node; 

당신은 초기화해야합니다 p 첫째 - 중 건설 기간 동안 (이 경우 당신의 "빈"목록에서 물리적으로 비어 있지 않으므로 특별히 처리해야합니다 (예 : 요소를 반복/제거 할 때) p == null 인 경우 add을 체크인하고 다르게 처리해야합니다.

사이드 참고 : p은 당신의 머리 요소를 가리 키도록되어, 그래서 다음 (r에 저장) 원래 값을 복원 add의 목록을 반복하는 것이 그것을 사용하는 위험입니다. 단순히 항상 그대로 두지 않고 반복을 위해 r을 사용하십시오. 버그에 대한 기회가 한 번 줄어 듭니다.

0

당신은 생성자에서 노드를 초기화해야합니다

p = new Node; 

여기에 있기 때문에 :

while(p!= NULL) 
{ 
    q = p; 
    p = p->lp; 
} 

q->lp = new node; 

p가 처음 NULL, 그래서 qNULL 될 것이다, ERGO q->lp로 연결 정의되지 않은 동작 및 cras h.

p을 초기화하거나 논리를 다시 생각하십시오.

+0

* 생성자에서 노드를 초기화해야합니다. *, 아니요, ** 구성원 초기화 목록 **에서 노드를 초기화해야합니다. –

+0

@Als가 생성자의 일부가 아닙니다. : P –

+0

언급 한 코드 문을 Member Initialization List에 추가 할 수 있습니까? 그럴 수 없다. 생성자 본문에만있을 수있다. 그래서 당신의 대답과 당신의 의견은 접선이다. –