C++ 在链表开头插入时读取内存时出错
因此,我有一个链表类,它本身在功能上做得很好,但是当涉及到实际内存使用时(泄漏,到处泄漏),它是非常令人厌恶的 因此,我将在其中实现一个基本的智能指针类,以便更好地处理内存,但是在这个想法的实际实现部分,我遇到了一些粗略的问题 我只特别提到了我认为与该问题相关的内容,但是,如果有任何部分没有包括在内,可能证明是有用的,请询问,我可以发布整个内容 main.cpp:C++ 在链表开头插入时读取内存时出错,c++,memory-management,smart-pointers,singly-linked-list,C++,Memory Management,Smart Pointers,Singly Linked List,因此,我有一个链表类,它本身在功能上做得很好,但是当涉及到实际内存使用时(泄漏,到处泄漏),它是非常令人厌恶的 因此,我将在其中实现一个基本的智能指针类,以便更好地处理内存,但是在这个想法的实际实现部分,我遇到了一些粗略的问题 我只特别提到了我认为与该问题相关的内容,但是,如果有任何部分没有包括在内,可能证明是有用的,请询问,我可以发布整个内容 main.cpp: int main() { smartLinkedList<char*> moo2; moo2.inser
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;
}
intmain()
{
smartLinkedList moo2;
2.插入式前部(“尾部”);
2.插入式前部(“一”);
2.插入式前部(“头部”);
对于(int j=0;j下一步;
如果(临时->下一步==NULL)
返回温度->数据;
}
返回温度->数据;
}
};
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;
}
};
#pragma一次
类引用计数
{
私人:
整数计数;
公众:
void add()
{
计数++;
}
int release()
{
返回——计数;
}
};
//对于非学习目的,boost有一个很好的智能指针
模板
sPtr类
{
私人:
*p型;
参考计数*r;
公众:
sPtr()
{
p=零;
r=新的引用计数();
r->add();
}
sPtr(类型*pValue)
{
p=pValue;
r=新的引用计数();
r->add();
}
sPtr(施工sPtr和sp)
{
p=sp.p;
r=sp.r;
r->add();
}
~sPtr()
{
如果(r->release()==0)
{
删除p;
删除r;
}
}
键入*get()
{
返回p;
}
类型和运算符*()
{
返回*p;
}
类型*运算符->()
{
返回p;
}
sPtr和操作员=(常数sPtr和sp)
{
if(this!=&sp)//自分配
{
/*如果(r->release()==0)
{
删除p;
删除r;
}*///当您获取没有引用的内容并将其设置为相等时,这将导致错误
p=sp.p;
r=sp.r;
r->add();
}
归还*这个;
}
};
节点h:
#pragma once
template <class type>
struct node
{
type data;
node *next;
node()
{
next = NULL;
}
};
#pragma一次
模板
结构节点
{
类型数据;
节点*下一步;
节点()
{
next=NULL;
}
};
从链表的goToFromFront(int)中的if语句中专门抛出“无法从0xfdfe01读取”的行,其中,在主循环中的点j=2处抛出错误。查看MSVS2010调试器时,temp->next是未知的(CXX0030:error,表达式无法计算),在我看来它应该转换为null,但表达式首先抛出了一个无法读取的错误
老实说,我不确定我做错了什么,因为这对我来说都是一个学习过程,任何批评都是高度赞赏的。提前谢谢 这些应该可以解决您的问题: 取消对sPtr运算符=中的代码的注释或使用交换习惯用法:
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;
}
通过使用侵入式引用计数而不是单独的引用计数,您可能会使事情变得更简单;更重要的是,您应该为
操作符=
实现使用复制和交换习惯用法。@Medinoc我在发布这篇文章之前,实际上很想继续重写引用计数,但我想我不想在无法完全测试的情况下意外添加另一个bug。感谢您提供的复制和交换参考,我以前没有听说过,我将很快实现它。您不会丢失太多代码,这些代码将使此完全编译。为节点添加引用和其他缺失的内容,如果我们能够自己完全构建它,我们就更有可能提供帮助。@MikeVine我添加了节点和我最近的一些更改。它应该可以在你这边编译,省去我来这里的明显错误。恐怕我不明白。除了第五行使用head.get()之外,您发布的代码与我的代码完全相同,它必须用作head本身是一个智能指针,接下来是一个节点*。不管这种细微差别如何,都会注释掉将在=运算符上递减的部分。除非在较低的级别上发生其他事情,否则我不确定refCount会在何处或如何减少。你能进一步解释一下你的意思吗?(也就是说,我认为你是对的,我确实认为它指向垃圾,我只是不理解如何/为什么)我在你的代码中取消了assign中的部分注释(应该按照建议使用swap进行显示或重写),以产生问题(在c++11中使用gcc)。然后我修复了“Insertafront”。使用head.get()的区别在于对构造函数(type*)的隐式调用,该构造函数创建了一个临时对象(您可以通过在“sPtr(type*pValue)”之前添加关键字“explicit”来禁止该隐式调用)。那个临时的有它自己的refcount,并且被销毁了。我想我开始更好地理解你的意思了,我想我理解错误发生的地方,但我不知道如何修复它。尝试执行temp->next=head会导致类型不匹配,我只能执行type->next=&*head或type->next=head.get(),我不知道如何实现显式,而几乎所有操作都会出错。你能给我看一些代码剪贴画什么的吗?答案更新了,现在我们有了你的“节点”版本。我用的是我的版本,所以我之前的评论并不完全适用于你的案例。这做得很完美,解决了一个我苦苦挣扎了几个小时的问题。谢谢你并没有表现出足够的感激。
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;
}
explicit sPtr(type *pValue)