| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 745 人关注过本帖
标题:类创建的堆栈
只看楼主 加入收藏
mfkblue
Rank: 5Rank: 5
等 级:职业侠客
帖 子:472
专家分:343
注 册:2008-12-21
结帖率:96.25%
收藏
已结贴  问题点数:20 回复次数:9 
类创建的堆栈
又出问题了.运行时出错,成员函数ADD第一次运行是没有出错的,增加第二个元素时出错,按运行顺序,错误好像出在析构函数,但却找不出有什么错。

#include <iostream.h>
template <class T>
class Stack
{
    public:
        Stack();
        ~Stack(){delete []stack;}
        Stack<T>& Add(const T& x);
        void Output(ostream& out) const;
        friend istream& operator>>(istream& in,Stack<T>& x);
    private:
        int top;
        int MaxTop;
        T *stack;
};


template <class T>
istream& operator>>(istream& in,Stack<T>& x)
{
    T t;
    cin>>t;
    x.Add(t);
    return in;
}

template <class T>
void Stack<T>::Output(ostream& out) const
{
    int n=top+1;
    for(int i=0;i<n;i++)
        out<<stack[i]<<" ";
    cout<<endl;
}

template <class T>
ostream& operator<<(ostream& out,Stack<T>& x)
{
    x.Output(out);
    return out;
}

template <class T>
Stack<T>::Stack()
{
    MaxTop=0;
    stack=new T[MaxTop+1];
    top=-1;
}



template <class T>
Stack<T>& Stack<T>::Add(const T& x)
{
    if((MaxTop-top)<1)
    {
        MaxTop=2*MaxTop+1;
        T *t=new T[MaxTop];
        for(int i=0;i<top+1;i++)
            t[i]=stack[i];
        delete []stack;
        stack=t;
    }
    stack[++top]=x;
    return *this;
}


void main()
{
    Stack <int> s;
    s.Add(2).Add(23);
    cout<<"s:"<<s;
}
搜索更多相关主题的帖子: 堆栈 
2009-08-22 22:33
mfkblue
Rank: 5Rank: 5
等 级:职业侠客
帖 子:472
专家分:343
注 册:2008-12-21
收藏
得分:0 
在网上找到这句话:
变量的作用域问题,如:你是在一个函数体中new的,却在另一个函数体中delete,这时的a变量已经失效了,这时delete会出现a为不认识的标识符的错误;   

文章出处:DIY部落(http://www.)
上面这个类问题就出在析构函数里的delete了,我必须在add这个函数体里new,在另一个函数体(析构函数)里delete,要怎样解决呢?
2009-08-25 23:02
missiyou
Rank: 5Rank: 5
等 级:贵宾
威 望:16
帖 子:531
专家分:218
注 册:2007-10-9
收藏
得分:5 
void main()
{
    Stack <int> s;
    s.Add(2).Add(23);
    cout<<"s:"<<s;
}

这里编译会错的,s.Add(2).Add(23); 这个函数参数是引用。不能直接传值的。
2009-08-25 23:16
mfkblue
Rank: 5Rank: 5
等 级:职业侠客
帖 子:472
专家分:343
注 册:2008-12-21
收藏
得分:0 
只要我去掉析构函数里的delete []stack,运行很正常。
刚才把&这符号去掉了,析构函数里的问题依旧,版主没回答到点子上的,现在的主函数里的add调用只是测试,正常运行时不会这样添加数据的.
弹出错误:damage after normal block(#43),网上查阅可能是不正常释放.
2009-08-25 23:32
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:0 
回复 2楼 mfkblue
肯定可以在一个函数里申请在另一个函数里释放。
比如在构造函数里动态分配的空间,在析构的时候肯定是能释放的。
你写的这个我还没来及看,一会看看,没准是别的错误。
2009-08-26 09:46
pangding
Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19Rank: 19
来 自:北京
等 级:贵宾
威 望:94
帖 子:6784
专家分:16751
注 册:2008-12-20
收藏
得分:10 
回复 5楼 pangding

重写了一下你的那个:
程序代码:
#include <iostream>
using namespace std;

template <class T>
class Stack
{
    public:
        Stack()
        {
            MaxTop = 1;
            stack = new T[MaxTop];
            top = -1;
        }
        ~Stack(){ delete[] stack; }

        Stack<T>& Add(const T& x);
        ostream& Output(ostream& out) const;

    private:
        int top;
        int MaxTop;
        T *stack;
};

template <class T>
Stack<T>& Stack<T>::Add(const T& x)
{
    if (top+1 == MaxTop)
    {
        T *t = new T[2*MaxTop];
        for (int i=0; i<MaxTop; i++)
            t[i] = stack[i];
        MaxTop *= 2;
        delete[] stack;
        stack = t;
    }
    stack[++top] = x;
    return *this;
}
template <class T>
ostream& Stack<T>::Output(ostream& out) const
{
    for (int i=0; i<top+1; i++)
        out << stack[i] << ' ';
    out << endl;

    return out;
}

int main()
{
    Stack <int> s;
    s.Add(2).Add(23);
    s.Output(cout);

    return 0;
}

主要是感觉你的那个逻辑有一点怪:
构造函数其实分配了一个元素的空间。但第一次调用Add的时候没有用这个空间,而是以为没地了,进而转去重新分配。但其实后来也只是删去了那个位置,重新分配的还是一个元素的空间。
不过我确实觉得这好像也不影响。但确实运行的时候出了错误,我没有仔细追踪这个错误是为什么产生的。
你这有一个值得注意的地方:
最开始的时候,MaxTop是0,但分的空间是 MaxTop+1 这么多。之后每次再分配空间就都是 MaxTop 这么多了。
这个逻辑不一致性,很容易导致错误。最好让逻辑保持一致,在开始设计的时候就要避免使用容易导致错误的方法。
另外其实一开始的时候就分配一些少量的空间是很有好处的:它只需要耗费很少的内存(比如只分配10个左右),但在开始的数次push就不用重新申请和拷贝了(这是很费时间的)。而不用像现在这样,如果我一开始就想插入10个元素,这样调用会导致5、6次内存的重新分配和转移。
最重要的是,现在这样,最开始的时候可能没有分配内存。MaxTop=0,显然(我想)你是为了避免之后特殊处理这种情况,才使用了new T[MaxTop+1],这种奇怪的方法。而如果像我说的那样做可以让各种情况比较统一。
2009-08-26 11:00
sunkaidong
Rank: 4
来 自:南京师范大学
等 级:贵宾
威 望:12
帖 子:4496
专家分:141
注 册:2006-12-28
收藏
得分:5 
#include "iostream"
#include"cstdlib"
using namespace std;
template <class T>
class Stack
{
    public:
        Stack();
        ~Stack(){delete []stack;}
        Stack<T>& Add(const T& x);
        void Output(ostream& out) const;
        friend istream& operator>>(istream& in,Stack<T>& x);
    private:
        int top;
        int MaxTop;
        T *stack;
};


template <class T>
istream& operator>>(istream& in,Stack<T>& x)
{
    T t;
    cin>>t;
    x.Add(t);
    return in;
}

template <class T>
void Stack<T>::Output(ostream& out) const
{
    int n=top+1;
    for(int i=0;i<n;i++)
        out<<stack[i]<<" ";
    cout<<endl;
}

template <class T>
ostream& operator<<(ostream& out,Stack<T>& x)
{
    x.Output(out);
    return out;
}

template <class T>
Stack<T>::Stack()
{
    MaxTop=0;
    stack=new T[MaxTop+1];
    top=-1;
}



template <class T>
Stack<T>& Stack<T>::Add(const T& x)
{
    if((MaxTop-top)<=1)
    {
        MaxTop=2*MaxTop+1;
        T *t=new T[MaxTop];
        for(int i=0;i<top+1;i++)
            t[i]=stack[i];
        delete []stack;
        stack=t;
    }
    stack[++top]=x;
    return *this;
}


int main(void)
{
    Stack <int> s;
    s.Add(2).Add(23);
    cout<<"s:"<<s;
    system("pause");
    return 0;
}
红颜色的部分逻辑有点问题,涉及数组越界访问,会出现异常

学习需要安静。。海盗要重新来过。。
2009-08-26 18:43
mfkblue
Rank: 5Rank: 5
等 级:职业侠客
帖 子:472
专家分:343
注 册:2008-12-21
收藏
得分:0 
我也觉得数组初始化大小为1,很不方便,只是想尽量按着书上的要求去做出这道题.果然还是你们高手厉害,我一直是在考虑释放空间怎么出错了,还debug一直追着stack的地址看.原来是申请时出错了,忘了算0*2+1还是等于1,不过按照构造函数里的办法,我在Add里重新申请时也用了&nbsp;T&nbsp;*t=new&nbsp;T[MaxTop+1];&nbsp;&nbsp;运行也正常了。谢谢大家了,这道题卡住我三天了,可以继续看下面的.

[ 本帖最后由 mfkblue 于 2009-8-26 20:08 编辑 ]

未标题-1 拷贝.jpg (116.66 KB)
图片附件: 游客没有浏览图片的权限,请 登录注册


未标题-1 拷贝.jpg (73.33 KB)
图片附件: 游客没有浏览图片的权限,请 登录注册
2009-08-26 20:07
mfkblue
Rank: 5Rank: 5
等 级:职业侠客
帖 子:472
专家分:343
注 册:2008-12-21
收藏
得分:0 
上面想编辑下把100K的图换成70K的,没想到还变成2张图了.

今天七夕,没有的祝愿大家找到一个。有了的祝你们好运.

[ 本帖最后由 mfkblue 于 2009-8-26 20:16 编辑 ]
2009-08-26 20:11
serious
Rank: 6Rank: 6
等 级:侠之大者
威 望:1
帖 子:81
专家分:497
注 册:2009-8-18
收藏
得分:0 
一个提示 : 在"Output"里,而不是用"for"循环你可以用迭代器.

比如 :
程序代码:
#include <iostream>
#include <iterator>
#include <vector>

using namespace std;

int main()
{
    int a[] = {0, 1, 2, 3};

    vector<int> v(a, a + sizeof(a)/sizeof(*a));

    copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
}


[ 本帖最后由 serious 于 2009-8-28 04:07 编辑 ]
2009-08-28 04:06
快速回复:类创建的堆栈
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015434 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved