2009-08-19 4 views
-3

주에서 코드를 감안할 때 :가비지 결과! C++ LinkedList의

// main.cpp 
wineries->insert(winery("Lopez Island Vinyard", "San Juan Islands", 7, 95)); 

일어날 것 두 가지 :

//winery.cpp 
winery::winery(const char * const name, const char * const location, 
       const int acres, const int rating) 
    : name(new char[strlen(name)+1]) 
    , location(new char[strlen(location)+1]) 
    , acres(0), rating(0) 
{ 

} 

:

  1. 와이너리 생성자는 내가 와이너리 개인 회원 intialized 한 곳 호출 작업이 끝나면 포인터 this의 결과에 가비지 값이 있습니다. 왜 이런거야? 올바르게 초기화하지 않습니까? 와이너리 생성자가 사망 한 후

  2. , 우리는 list::insert(const winery &winery) 기능으로 이동 :

    void list::insert(const winery& winery) 
    { 
        node *NodePtr = new node(winery); 
        // NodePtr->item has the garbage. 
        NodePtr->item = winery; 
    } 
    
    list::node::node(const winery& winery) 
    { 
        // This works because I have a default constructor for the winery object 
        // and *only* for that reason... 
        // How can I use the node constructor without having to use a default constructor for the winery class? 
    } 
    

    이유는 와이너리 생성자에 전달 된 값의 결과로 쓰레기는 무엇입니까?

    와이너리 공공 멤버 함수는 name, location, acresrating는 와이너리 클래스에 대한 모든 개인 회원이있는 곳, 다음과 같습니다. 매개 변수를 가진 이러한 기능없이

    winery::winery() 
    { 
        // do nothing default constructor 
        // only here so I can add the &winery to the node constructor.. 
    } 
    
    winery::~winery() 
    { 
        delete location; 
        delete name; 
        // your code here 
    } 
    
    const char * const winery::getName() const 
    { 
        //winery *wine_t = new winery(); 
        const char cName[5] = "four"; 
        // just to see if it still gives garbage.. 
        return cName 
    } 
    
    const char * const winery::getLocation() const 
    { 
        // return one of winery's private members. 
        // It *will* crash when this function is called. 
        // *That* might be the issue with **garbage values** return location; 
    } 
    

    , 그것은 ... 그것은 어려운 wineryPtr 객체를 통해 속성을 전송 한 다음이 LinkedList의에 전체 와이너리 개체를 추가하는 것이 논리적 일 것입니다 수

    // list.h 
    #ifndef _LIST_ 
    #define _LIST_ 
    
    #include <ostream> 
    #include "winery.h" 
    
    using namespace std; 
    
    class list 
    { 
    public: 
        list(void);    // constructor 
        virtual ~list(void); // destructor 
        ... 
        void insert(const winery& winery); 
        winery * const find(const char * const name) const; 
    
    
    private: 
        struct node 
        { 
          node(const winery& winery);  // constructor 
         winery item; 
         node * nextByName; 
         node * nextByRating; 
         }; 
    
        node * headByName; 
        node * headByRating; 
    }; 
    
    #endif // _LIST_ 
    

내 질문에 약간의 흩어져 있고 도움을 줄 시간이있는 사람이 있기를 바랍니다.

+2

질문을 올바르게하기 위해 노력하십시오. 나는 당신이 더 좋은 대답을 얻을 것이라는 것을 보증합니다 –

+0

당신이 말하는이 포인터는 어디에서 왔습니까? – Zed

+0

무슨 뜻인지 이해가 안 되니? 쓰레기 값은 무엇을 의미하며 쓰레기인지 어떻게 결정합니까? 가비지 데이터를 가져 오는 위치 및 가비지 테스트 방법을 포함하여 문제를 재현하는 코드를 보여줍니다. – jalf

답변

2

아마 와이너리 클래스에서 copy-constructor 및 operator =이 부족한 것입니다. 목록에 삽입하면 이름과 위치 포인터가 복사되지만 가리키는 문자열은 공유됩니다. 그런 다음 복사 한 인스턴스가 범위를 벗어나 인스턴스가 삭제됩니다.

디버거에서 namelocation을 만든 다음 생성자에서 중단 점을 배치 한 다음 소멸자에서도 중단 점을 배치하십시오. 할당 횟수가 할당 취소 횟수와 일치하지 않음을 알 수 있습니다.

+0

나는 와이너리 클래스의 연산자와 << 와이너리 클래스에 복사기를 가지고 있습니다. – user40120

+0

연산자가 있습니까? –

0

괜찮습니다. 어떻게 든 타이핑을 할 때 좀 더 명확하게 볼 수 있습니다.

//winery.cpp 
winery::winery(const char * const name, const char * const location, 
       const int acres, const int rating) 
    : name(new char[strlen(name)+1]) 
    , location(new char[strlen(location)+1]) 
    , acres(0), rating(0) 
{ 
}

:

winery::winery(const char * const name, const char * const location, const int acres, const int rating): name(new char[strlen(name)+1]), location(new char[strlen(location)+1]), acres(0), rating(0) 
{ 
    strcpy_s(this->name, MAXNAME_SZ, name); 
    strcpy_s(this->location, MAXNAME_SZ, location); 
    this->acres = acres; 
    this->rating = rating; 
} 

, MAXNAME_SZ이 와이너리 생성자의 구현 나를 위해 제대로 보이지 않습니다 (75)

+0

"name"및 "location"멤버 변수에 대한 공간을 할당해야합니다. –

2

의 CONST의 INT는 다음과 같습니다

내가 무엇을 의미입니다 먼저 이름 및 위치 멤버 변수에 메모리를 할당했지만 입력 매개 변수에서 내용을 srtcpy하지 않았습니다.

둘째, 에이커 및 등급 멤버 변수를 0으로 시작했습니다. 그것은 당신의 의도입니까?

그리고 마지막으로 복사 생성자와 대입 연산자가 필요합니다!

2

문제의 많은 원인은 아마 당신의 노드 값에 의해 winery 개체를 포함하고 winery 기본 생성자가 locationnameNULL을 할당되지 않는다는 사실이다. insert 작업이 node 개체를 할당 할 때 기본 생성자를 사용하여 winery 개체를 만드는 경우 NodePtr->item 할당이 발생할 때 개체를 덮어 씁니다. 이로 인해 대입 연산자가 호출됩니다. 할당 연산자는 기본 생성자가 올바른 작업을 수행하지 않으면 올바르게 구현 될 수 없습니다.

내가 필요없이 내가 list::node::node(const winery&),하지만 같은 winery::operator=(const winery&), 또는 winery::winery(const winery&) 보면 내가 제대로 구현 될 수 있다는 상상할 수없는 것을 알 수 없기 때문에 여기에 몇 가지 가정을하고있어 winery 멤버는 기본적으로 알려진 값으로 설정 .

어떤 작업이 호출되는지 완전히 이해할 때까지 언급 한 insert() 호출을 신중하게 살펴볼 것입니다. 다음 프로그램을 고려하십시오.

#include <iostream> 

struct node { 
    node() { std::cout << "default constructor" << std::endl; } 
    node(int) { std::cout << "int constructor" << std::endl; } 
    node(node const&) { std::cout << "copy constructor" << std::endl; } 
    ~node() { std::cout << "destructor" << std::endl; } 
    node& operator=(node const&) { std::cout << "assignment" << std::endl; } 
}; 

void 
insert(node const& a) { 
    node b(a); 
    node c; 
    b = c; 
} 

int 
main() { 
    insert(node(1)); 
    return 0; 
} 

실행을하고 출력이 왜 당신이 따를 수 있는지 :

int constructor 
copy constructor 
default constructor 
assignment 
destructor 
destructor 
destructor 

당신의 문제는 기본 생성자, 복사 생성자와 대입 연산자가 옳은 일을하지 않는 것입니다. 다행히도 이것은 당신을 올바른 길로 인도 할 것입니다.