0

したがって、機能的にはそれ自体で素晴らしい仕事をするこのリンクリストクラスがありますが、実際のメモリ使用量に関してはかなりうんざりです (リーク、どこでもリーク)。

そのため、メモリをより適切に処理するために、基本的なスマート ポインター クラスを実装していますが、このアイデアの実際の実装部分でいくつかの大まかなポイントを見つけました。

問題に関連すると思われるもののみを具体的に含めましたが、含まれていない有用な部分がある場合は、質問してください。すべてを投稿できます.

main.cpp:

int main()
{
    smartLinkedList<char*> moo2;
    moo2.insertAtFront("tail");
    moo2.insertAtFront("one");
    moo2.insertAtFront("head");
    for(int j = 0; j < moo2.length() ; j++)
        cout << moo2.goToFromFront(j) << endl;

    cin.ignore(1);
    return 0;
}

smartLinkedList.h:

template <class type>
class smartLinkedList
{
private:
    int size;
    sPtr<node<type>> head; 

public:
    smartLinkedList(): head(NULL), size(0) {}
    bool insertAtFront(type obj)
    {
        sPtr<node<type>> temp(new node<type>);
        temp->data = obj;
        temp->next = head.get();
        //For future reference, &*head = head.get()
        head = temp;

        //delete temp;

        size++;
        return true;
    }
    type goToFromFront(int index)
    {
        sPtr<node<type>> temp = head;

        for(int i = 0; i < index; i++)
        {
            temp = temp->next;

            if(temp->next == NULL)
                return temp->data;
        }

        return temp->data;
    }
};

smartPointer.h:

#pragma once

class referenceCount
{
private:
    int count;
public:
    void add()
    {
        count++;
    }
    int release()
    {
        return --count;
    }
};

//for non-learning purposes, boost has a good smart pointer
template <class type>
class sPtr
{
private:
    type *p;
    referenceCount *r;
public:
    sPtr()
    {
        p = NULL;
        r = new referenceCount();
        r->add();
    }
    sPtr(type *pValue)
    {
        p = pValue;
        r = new referenceCount();
        r->add();
    }
    sPtr(const sPtr<type> & sp)
    {
        p = sp.p;
        r = sp.r;
        r->add();
    }
    ~sPtr()
    {
        if(r->release() == 0)
        {
            delete p;
            delete r;
        }
    }

    type* get()
    {
        return p;
    }

    type& operator*()
    {
        return *p;
    }
    type* operator->()
    {
        return p;
    }
    sPtr<type>& operator=(const sPtr<type>& sp)
    {
        if (this != &sp) //self assignment
        {
            /*if(r->release() == 0)
            {
                delete p;
                delete r;
            }*/ //this will cause an error when you take something with no references and set it equal to something

            p = sp.p;
            r = sp.r;
            r->add();
        }
        return *this;
    }
};

node.h:

#pragma once

template <class type>
struct node
{
    type data;
    node *next;

    node() 
    {
        next = NULL;
    }
};

リンク リストの goToFromFront(int) の if ステートメントから "Cannot read from 0xfdfdfe01" を明確にスローする行。ここで、メイン ループのポイント j = 2 でエラーがスローされます。MSVS2010 デバッガーを見ると、temp->next は不明です (CXX0030: エラー、式を評価できません)。null に変換する必要があるように見えますが、式は最初に読み取れないエラーをスローしています。

正直なところ、何が間違っていたのかわかりません。これはすべて学習プロセスであるため、批判は大歓迎です。前もって感謝します!

4

1 に答える 1

0

これらはあなたの問題を解決するはずです:

operator= の sPtr のコードのコメントを外すか、swap イディオムを使用します。

sPtr<type>& operator=(const sPtr<type>& rhs)
{
    if (this != &rhs) // self assignment
    {
        sPtr<type> tmp(rhs);
        std::swap(this->p, tmp.p);
        std::swap(this->r, tmp.r);
    }
    return *this;
}

template <class T>
class node
{
public:
    T data;
    sPtr<node<T> > next;
};

bool insertAtFront(type obj)
{
    sPtr<node<type>> temp(new node<type>);
    temp->data = obj;
    temp->next = head;
    head = temp;
    size++;
    return true;
}

goToFromFront では、「temp = temp->next;」temp->next を 1 回使用して refCount を作成しました。「temp」が範囲外になると、その内容が破棄されるため、「head->next」はガベージを指します。

sPtr > = T* を実行すると、一時オブジェクトが暗黙的に作成され、次のように sTtr コンストラクターとして宣言できます。

explicit sPtr(type *pValue)
于 2013-08-20T10:12:15.857 に答える