我开始学习C ++,所以我决定尝试实现一个能够存储数值的类 为了增加一点挑战,我决定让它排序:堆栈的元素必须从顶部到底部按升序排序。 我决定使用NaN来表示一个空堆栈。
所以这是hpp文件:
#ifndef MYMSS2_RENAME_ME_HPP
#define MYMSS2_RENAME_ME_H
class mySortedStack{
public:
double info;
mySortedStack * next;
mySortedStack();
mySortedStack(double a);
mySortedStack(const mySortedStack& a);
~mySortedStack();
double top();
double pop();
void push(double a);
int len();
};
#endif
这是cpp文件:
#include <iostream>
#include "myMSS2_RENAME_ME.hpp"
#include <math.h>
using namespace std;
mySortedStack::mySortedStack(){
//cout<<"Inside empty constuctor"<<endl;
info=NAN;
next=NULL;
//cout<<"Leaving empty constuctor"<<endl;
}
mySortedStack::mySortedStack(double a){
//cout<<"Inside normal constructor"<<endl;
info=a;
next=NULL;
//cout<<"Leaving normal constuctor"<<endl;
}
mySortedStack::mySortedStack(const mySortedStack& a){//this should be able to do deepcopies
//cout<<"Inside copy constructor"<<endl;
info=double(a.info);
next=new mySortedStack;
next=a.next;
//cout<<"Leaving copy constuctor"<<endl;
}
mySortedStack::~mySortedStack(){
//cout<<"Inside destructor"<<endl;
delete this;
}
double mySortedStack::top(){
return info;
}
void mySortedStack::pop(){
double retVal;
mySortedStack *tempStack = this->next;
retVal = info;
info = tempStack->info;
next = tempStack->next;
tempStack->next = NULL;
delete tempStack;
return retVal;
}
void mySortedStack::push(double a){
//cout<<"Pushing!"<<endl;
if (isnan(info)){//if stack is empty
info=a;
}
else{
mySortedStack *pushed=new mySortedStack();
if(info>a){//if the pushed element will be placed at the top
pushed->info=info;
pushed->next=next;
info=a;
next=pushed;
}else{//else
mySortedStack *currentNode=this;
while(currentNode->next->info<a){
currentNode=currentNode->next;
}
mySortedStack *pushed=new mySortedStack();
pushed->info=a;
pushed->next=currentNode->next;
currentNode->next=pushed;
}
}
}
int mySortedStack::len(){
int i=1;
mySortedStack currentNode=*this;
if (isnan(info)){
return 0;
}
while (currentNode.next!=NULL){
i+=1;
currentNode=*currentNode.next;
}
return i;
}
这编译得很好(我在Windows 8上使用Dev C ++)。
所以我尝试在cpp文件中添加main
函数来运行一些测试:
int main(){
mySortedStack mss0;
mySortedStack mss1(7);
mySortedStack mss2=mss1;
mss1.info=6;
cout<<mss1.info<<' '<<mss2.info<<endl;//copy constructor seems to work! output is '6 7'
system("PAUSE");
mss1.push(4);
mss1.push(5);
//the next piece of code is supposed to show the whole stack
bool flag=true;
mySortedStack inspected=mss1;
while(flag){
cout<<inspected.info<<endl;
if(inspected.next==NULL){
flag=false;
cout<<"NULL found!"<<endl;
}
else{
inspected=*inspected.next;
}
}
//seems correct. Output is:
//'4
//5
//6
//NULL found!'
system("PAUSE");
return 0;
}
Aaaannd来了!分段错误!(确切错误消息:程序接收信号SIGSEGV,分段错误)它似乎发生在return 0
之前。
添加一些cout<<
后,似乎问题出在我的析构函数(无限循环)中。由于我不知道析构函数的哪个调用使得这个,我既不知道问题是由于析构函数本身还是我在类方法或其他任何地方操作指针的方式。我试图在纸上画出我的每个方法中发生的事情,一切似乎都很好
我做错了什么?
非常感谢你提前。
答案 0 :(得分:4)
mySortedStack::~mySortedStack(){
//cout<<"Inside destructor"<<endl;
delete this; // Uuuh ?
}
......我真的不知道该回答的内容。
编辑:事实上,我发现了一些东西:
mySortedStack::mySortedStack(const mySortedStack& a){
// ...
next=new mySortedStack; // Hello brand new object !
next=a.next; // Goodbye leaked object !
// ...
}
答案 1 :(得分:1)
是的,但具体来说,请致电&#39;删除这个&#39;您正在尝试删除包含析构函数的当前对象。删除调用析构函数,调用delete等,从而调用循环。
析构函数在那里,所以你可以释放你的类被分配的任何内存。这样当有人调用delete mySortedStackInstance(无论它被调用了什么)时,你的类就不会泄漏内存。
我想我应该添加一下,这样你就不会对你班级中的析构函数实际上有什么混淆。
答案 2 :(得分:0)
分段来自这一行
mySortedStack inspected=mss1;
你必须编写适当的拷贝构造函数。
您的代码中还有其他内存问题:
mySorted堆栈正在自杀。这是一种糟糕的风格。
mySortedStack::~mySortedStack(){
//cout<<"Inside destructor"<<endl;
delete this;
}
你的析构函数应该是这样的
mySortedStack::~mySortedStack(){
//cout<<"Inside destructor"<<endl;
delete this->mySortedStack;
}
另一种缺乏风格的是名称:一个类和一个memeber共享相同的名称。很难读懂。