2012-05-07 6 views
0

이것은 C++ 프로그래밍 문제입니다.Linux의 C++에서 스마트 포인터 (예 : auto_ptr r shared_ptr)를 사용하여 링크 목록 데이터 구조를 생성하는 방법은 무엇입니까?

다른 함수가 목록을 사용할 수 있도록 목록을 생성하고 포인터를 반환해야합니다. 코드는 작동하지만 목록에 각 새 노드를 할당하기 위해 "new"를 사용하기 때문에 메모리 누수가 발생합니다.

목록을 사용한 후에는 메모리를 해제해야합니다. 다음과 같이

내 코드는 다음과 같습니다

#include <iostream> 
#include <stack> 
#include <memory> 
using namespace std; 

class linkListClass 
{ 

private: 
     int data; 
     auto_ptr<linkListClass> nextData; 
public: 
    auto_ptr<linkListClass> buildLinkList(const int size); 
    int getData(){return data;}; 
    int printListBackward(auto_ptr<linkListClass> listroot); 
}; 

inline auto_ptr<linkListClass> linkListClass::buildLinkList(const int size) 
{ 
      linkListClass *trueRoot; 
      linkListClass *listRoot = new linkListClass ; 
      linkListClass *trueRoot; 
      linkListClass *listRoot = new linkListClass ; 
      // data is random int 
      for (int i = 0; i < size ; ++i) 
      { 
        if (i < size -1) 
        { 
          if (i == 0) 
          { 
            listRoot->data = rand()%10 ; 
            listRoot->nextData = auto_ptr<linkListClass>(0) ; 
            trueRoot = listRoot ; // transfer ownership 
          } 
          else{ 
            listRoot->nextData = auto_ptr<linkListClass> (new linkListClass); // segmentation fault 
            listRoot->data = rand()%10 ; 
            listRoot = listRoot->nextData ; 
          } 


        } 
        else 
          listRoot->nextData = auto_ptr<linkListClass>(0) ; 

      } 

    cout << "the built list has " << size << " data \n\n" ; 
    return trueRoot; 
} 
inline int linkListClass::printListBackward(auto_ptr<linkListClass> listroot) 
{ 
    int counter =0 ; 
    stack<int> outputStack; 
    cout << "print the list forward \n\n" ; 
    //if (listroot != NULL) 
    cout << "print the list forward \n\n" ; 
    //if (listroot != NULL) 
    if (listroot.get() != 0) 
    { 
      do 
      { 
        try{ 
          cout << listroot->getData() << " \t " ; 
          outputStack.push(listroot->data); 
          listroot = listroot->nextData; 
          ++counter; 
          cout << "in printListBackward counter is " << counter << endl; 
          //if (listroot == 0) break; 
        } 
        catch(exception& e) 
        { 
          cout << "an error is " << e.what() << endl; 
          return 1; 
        } 

      //}while(listroot != 0); 
      }while(listroot.get() != 0); 
      cout << "in printListBackward outof do while \n\n " << endl ; 
    } 
    else 
    { 
      cout << "the input list is null \n\n" << endl; 
      return 1; 
    } 
    cout << endl ; 
    cout << "there are" << counter << " data in the list \n\n " << endl ; 
    cout << "print the list backward \n\n" ; 

    if (outputStack.empty() == 1) 
    { 
      cout << "the ouytput queu is empty \n\n " << endl ; 

      cout << "the ouytput queu is empty \n\n " << endl ; 
      return 1; 
    } 
    else 
    { 
      do 
      { 
        cout << outputStack.top() << " \t" ; 
        outputStack.pop(); 
      }while(outputStack.empty() == 0); 
    } 
    cout << endl; 
    cout << "there are" << counter << " data in the list \n\n " << endl ; 
    return 0 ; 
    } 

    int main() 
    { 
    const int listSize = 5; 
    linkListClass linkListObj; 
    auto_ptr<linkListClass> myRoot ; //= linkListClass::buildLinkList(listSize); 
    myRoot = linkListObj.buildLinkList(listSize); 
    linkListObj.printListBackward(myRoot); 


    return 0; 
    } 

    // EOF 

코드는 세그먼트 오류를 ​​가지고 있기 때문에 auto_ptr은 전송 pointee의 소유권

listRoot = listRoot->nextData 

후 연결리스트가 고장이되도록하고 listRoot-> nextData NULL입니다.

내가 TR1 :: shared_ptr을하고 waek_ptr

tr1::weak_ptr<linkListClass> wp1 = listRoot->nextData; 
    listRoot = wp1.lock() ; 
    listRoot = listRoot->nextData ; 

을 시도했지만 내가 오류 컴파일있어 : 어떤 도움을 이해할 수있을 것이다

listPtSharedptr.cpp:63: error: conversion from linkListClass* to non-scalar type std::tr1::weak_ptr requested listPtSharedptr.cpp:65: error: no match for operator= in listRoot = listRoot.std::tr1::shared_ptr<_Tp>::operator-> with _Tp = linkListClass->linkListClass::nextData /usr/lib/gcc/x86_64-redhat-linux/4.1.2/../../../../include/c++/4.1.2/tr1/boost_shared_ptr.h:486: note: candidates are: std::tr1::shared_ptr& std::tr1::shared_ptr::operator=(const std::tr1::shared_ptr&)

합니다.

감사합니다.

+0

printLastBackward()에 auto_ptr <>을 전달하고 싶지는 않지만 대신 일반 포인터를 전달하십시오. –

답변

2

다음은 "buildLinkList"함수의 수정 된 기능입니다. 이제는 작동합니다. 한 가지 차이점이 있습니다. FIFO 목록을 작성 중입니다. 이 버전은 LIFO 목록을 만듭니다. FIFO는 auto_ptrs로 생성하기가 어렵습니다. 나중에이 작업 예제를 사용하여 shared_ptrs를 사용하여 FIFO 목록으로 변환하려고 시도 할 수 있습니다.

inline auto_ptr<linkListClass> linkListClass::buildLinkList(const int size) 
{ 
      auto_ptr<linkListClass> trueRoot(0); 
      auto_ptr<linkListClass> listRoot(0); 
      // data is random int 
      for (int i = 0; i < size ; ++i) 
      { 
        listRoot = auto_ptr<linkListClass> (new linkListClass); 
        listRoot->data = random()%10 ; 
        listRoot->nextData = trueRoot; 
        trueRoot = listRoot; 
      } 
    cout << "the built list has " << size << " data \n\n" ; 
    return trueRoot; 
}