在链表的开头插入时读取内存时出错

Error reading memory while inserting at the head of a linked list

本文关键字:读取 出错 内存 插入 链表 开头      更新时间:2023-10-16

所以我有一个链表类,它本身在功能上做得很好,但当涉及到实际内存使用时(到处都是泄漏),它非常恶心。

因此,我将在其中实现一个基本的智能指针类,以便更好地处理内存,但我在这个想法的实际实现部分遇到了一些粗略的问题。

我只具体包括了我认为与该问题相关的内容,然而,如果有任何未包括的部分可能有用,请询问,我可以发布整个内容。

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,但表达式首先抛出了一个无法读取的错误。

老实说,我不确定自己做错了什么,因为这对我来说都是一个学习过程,所以任何批评都是非常值得赞赏的。提前感谢!

这些应该可以解决您的问题:

取消对sPtr的operator=中的代码的注释或使用交换习惯用法:

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;'创建了一个refCount,其中一个使用temp->next。当"temp"超出范围时,它会破坏其内容,因此"head->next"指向垃圾。

当您执行sPtr>=T*时,您隐式地创建了一个临时对象您可以将sTtr构造函数声明为:

explicit sPtr(type *pValue)