2009-12-11 4 views
7

이중 연결 목록 클래스를 구현해야하는 할당이 있습니다.C++의 이중 연결된 목록

struct node { 
    node *next; 
    node *prev; 
    T  *o; 
}; 

이 구조체의 멤버 '데이터'포인터되지 않은 경우 클래스를 작성 훨씬 쉽게 될 것이라고 나에게 보인다는 다음과 같이 몇 가지 이유를 들어 그들은 노드 struct을 정의했다. 말할 것도없이 나는 그것을 바꿀 수 없기 때문에 나는 단지 그것을 해결해야 할 것입니다. 디버깅 ddd를 사용하는 동안

template <typename T> 
void Dlist<T>::insertFront(T *o) { 
    node *np = new node; 
    T val = *o; 

    np->o = &val; 
    np->prev = NULL; 
    np->next = first; 

    if (!isEmpty()) { 
     first->prev = np; 
    } else { 
     last = np; 
    } 
    first = np; 
} 

내가 모든 것을 잘 모든 것을 가져 주위에 당신이 수 있지만 두 번째 시간을 삽입 처음 작동하는지 깨달았다 : 나는 다음과 같이 목록의 시작 부분에 요소를 추가하는 방법을 구현하는 시도 새로운 요소에 'val'을 설정하자마자 val의 메모리 주소가 사용 된 이후 첫 번째 요소를 "덮어 씁니다". 나는 단지 'val'변수를 다음과 같이하는 대신에 다른 일을 시도했다.

T *valp = new T; 
T val; 
valp = &val; 
val = *o; 

np->o = valp 

이것은 작동하지 않는 것 같다. 이것이 방금 추가 메모리 누수와 함께했던 것보다 훨씬 복잡한 형태이기 때문에 이것이라고 생각합니다 :)

올바른 방향으로 어떤 아이디어/포인터가 좋을 것입니다.

+4

1. –

+0

이 부분을 살펴보면 첫 번째 답변이 문제를 이해하는 데 도움이 될 수 있습니다. http://stackoverflow.com/questions/5727/what-are-the-barriers-to-understanding-pointers-and-what-can-be -done-to -comecome – Dan

+0

기회가 생기면 이것도 한번보세요 : http://stackoverflow.com/questions/599308/proper-stack-and-heap-usage-in-c - 스택과 힙 할당. – Dan

답변

6

사용자가 만든 T val은 자동 변수입니다. 귀하의 실수는 그 스택 변수에 주소를 저장하는 것입니다.

의심되는 것처럼 힙에 공간을 할당하려면 new을 사용해야하지만 데이터 포인터는 new에 의해 반환 된 주소를 직접 가리켜 야합니다.

최신 시도에서 실수는 여기에 있습니다 : 당신은 가능성이 복사 발의 데이터하려고 할 때

valp = &val; 

당신은, 다른 곳valp에 점 (발의 주소를)하지 변화 그것의 주소.

함수에 전달 된 데이터는 valp이 가리키는 새 메모리에 복사해야합니다.

+0

Ahh. 왜 값을 읽으려고했을 때 값이 -1074723840으로 돌아가는 지 이해할 수 있습니다. 그래도이 문제를 해결하는 방법을 아직 확신 할 수는 없지만 도움이됩니까? 내 검색에서 나를 도울 수있는 키워드를 알려주시겠습니까? 감사. – blcArmadillo

+1

그냥 nitpicking : val은 임시가 아닙니다. 그것은 "자동"변수, 일명 스택 변수입니다. 그렇지 않으면 좋은 대답입니다. – Dan

+0

http://en.wikipedia.org/wiki/Automatic_variable – Dan

0
T val = *o; 

    np->o = &val; 

이 부분은 의심스러운 부분입니다. 힌트는 일단 함수가 범위를 벗어나면 함수의 스택에 할당 된 메모리를 사용할 수 없다는 것입니다.

4

나는 당신이이 일을해야한다고 생각하지 않습니다

T val = *o; 

강사는 아마 당신을위한 계획, 노드 구조에서 o 회원이 포인터이며, insertFront에 매개 변수는 포인터이기 때문에 주어진 포인터를 가져 와서 목록에 저장하려면 객체의 복사본을 만들고 포인터를 저장하십시오. o 포인터를 insertFront에 전달하여 노드의 o 구성원으로 저장하면 OK입니다.

+1

전적으로 동의합니다. 그것은 오히려'np-> data = o; '이어야합니다. –

+0

반드시 그런 것은 아닙니다. 전달 된 T *가 동적으로 할당되는지 여부와 DList가 소유권을 가져야하는지 또는 사본을 만들어야하는지 여부를 설명하는 주석이 있어야합니다. 당신이 그 질문들에 대한 답을 모른다면 당신은 그것을 행운을 제외하고 정확하게 구현할 수 없을 것입니다. – Dan

+1

@Sammy, 네가 'np-> data = new (* o);가 아니어야한다는 것을 어떻게 알 수 있니? – Dan

0

코드는 node의 당신의 정의에 맞지 않는 - node에 당신이 data 멤버를 정의하고 있지만 코드에서 대신 o을 사용하고 있습니다.데이터에 대한 노드 자체를위한 하나, 하나가 가리거야 객체 - 어떤 경우

, 각 노드를 추가하는 두 개의 동적 할당을해야 할 것입니다. 해당 데이터 객체를 할당 할 때 노드의 포인터에 new의 반환 값을 직접 할당 할 수 있습니다. 그런 다음 포인터가 전달 된 데이터 객체를 방금 할당 한 데이터 객체에 복사해야합니다.이 객체는 노드의 포인터가 가리키는 포인터입니다.

+0

좋은 캐치. 그래서 그것을 복사 한 후 구조체를 수정하고 다른 곳을 변경하는 것을 잊어 버렸습니다. – blcArmadillo

0

당신 포인터 페이로드가 불편하다고 생각합니다. 하지만 어쩌면 목록이처럼 기존 개체의 상단에 링크 을 만들 수하기위한 것입니다 : 존경하는 숙제 면책 조항에 대한

struct A { int i; }; 
A as[10] = { 1,2,3,4,5,6,7,8,9,10 }; 

LinkedList primes_in_my_data; 
insertFront(primes_in_my_data, &as[1]); 
insertFront(primes_in_my_data, &as[2]); 
insertFront(primes_in_my_data, &as[3]); 
insertFront(primes_in_my_data, &as[5]); 
insertFront(primes_in_my_data, &as[7]); 

// now I have a linked list of primes, and caused no extra memory allocation 
// (except for the list overhead)