标题:用operator<<( )方法输出有new动态分配的类对象时造成程序的终止运行问题? ...
只看楼主
沿途有鬼
Rank: 1
等 级:新手上路
帖 子:68
专家分:0
注 册:2008-7-20
 问题点数:0 回复次数:7 
用operator<<( )方法输出有new动态分配的类对象时造成程序的终止运行问题?
//头文件
#ifndef COW_H_
#define COW_H_
#include<iostream>
using std::ostream;
using std::istream;

class Cow
{
    char name[20];
    char * hobby;
    double weight;
    int len;
public:
    Cow();
    Cow(const char * nm,const char * ho,double wt);
    Cow(const Cow & c);
    ~Cow();
    Cow & operator=(const Cow & c);
    //Cow & operator=(const char * c);
    void ShowCow()const;
    friend ostream & operator<<(ostream & os,const Cow t);
};

#endif

//源文件
#include<iostream>
#include"cow.h"


Cow::Cow()
{
    hobby=new char[1];
    hobby[0]='\0';
        
strcpy(name,"no name");
    weight=0;

}
Cow::Cow(const char * nm,const char * ho,double wt)
{
strncpy(name,nm,20);
    name[20]='\0';
    len=strlen(ho);
    hobby=new char[len+1];
    strcpy(hobby,ho);
    weight=wt;
}

Cow::Cow(const Cow & c)
{
    strcpy(name,c.name);
    len=c.len;
    hobby=new char[len+1];
    strcpy(hobby,c.hobby);
    weight=c.weight;
}
Cow::~Cow()
{
    delete [] hobby;
}
Cow & Cow::operator=(const Cow & c)
{
    if(this==&c)
        return *this;
    delete [] hobby;
    len=c.len;
    hobby=new char[len+1];
    strcpy(name,c.name);
    strcpy(hobby,c.hobby);
    weight=c.weight;
    return *this;
}

void Cow::ShowCow()const
{
    using std::cout;
    using std::endl;
    cout<<"Name is: "<<name<<" ,hobby is: "<<hobby<<" ,weight is: "<<weight<<endl;
}

ostream & operator<<(ostream & os,const Cow t)
{
    using std::cout;
    using std::endl;
    cout<<"Name is: "<<t.name<<" ,hobby is: "<<t.hobby<<" ,weight is: "<<t.weight<<endl;
        return os;
}

//mian()
#include<iostream>
#include"cow.h"

int main()
{
    using std::cout;
    Cow nu1("xiaoxiaoqiang","baoyuan",50);
    Cow nu2;
    Cow temp;
//    nu1.ShowCow();
    cout<<nu1;
//    nu2.ShowCow();
    cout<<nu2;
    nu2=nu1;
//    nu2.ShowCow();
    cout<<nu2;
    return 0;
}

我的问题是为什么用cout<<nu1输出会造成程序的终止,我的深度复制构造函数和析构函数都写了啊,如果我把main()改成用ShowCow输出则没有问题,请问这个是怎么回事啊,我做了好几道关于new动态分配类中字符串的题都遇到了这个问题,我很想知道到底是什么问题,大侠们帮帮我啊~!
#include<iostream>
#include"cow.h"

int main()
{
    using std::cout;
    Cow nu1("xiaoxiaoqiang","baoyuan",50);
    Cow nu2;
    Cow temp;
    nu1.ShowCow();
//    cout<<nu1;
    nu2.ShowCow();
//    cout<<nu2;
    nu2=nu1;
    nu2.ShowCow();
//    cout<<nu2;
    return 0;
}

下面是我用VC6.0创好了的工程,大家直接点击121Cow.dsw运行看看帮我找找问题,感激不尽啊~
121Cow.rar (852.27 KB)


[[it] 本帖最后由 沿途有鬼 于 2008-8-12 16:23 编辑 [/it]]
搜索更多相关主题的帖子: Cow cout const new 动态 
2008-08-12 16:10
xlh5225
Rank: 2
等 级:论坛游民
威 望:2
帖 子:188
专家分:25
注 册:2007-8-14
得分:0 
首先,你的程序错误是非常隐蔽的,请注意你调用的下面函数:
    friend ostream & operator<<(ostream & os,const Cow t);
    在main函数中,出错行是cout << nu2.
下面我们来看看是那里的问题:
注意你的第个参数,是按值传递的,也就是说在参数压
2008-08-12 16:41
zerocn
Rank: 1
等 级:新手上路
帖 子:126
专家分:0
注 册:2006-4-11
得分:0 
楼上一说,恍然大悟啊
2008-08-12 16:52
xlh5225
Rank: 2
等 级:论坛游民
威 望:2
帖 子:188
专家分:25
注 册:2007-8-14
得分:0 
首先,你的程序错误是非常隐蔽的,请注意你调用的下面函数:
    friend ostream & operator<<(ostream & os,const Cow t);
    在main函数中,出错行是cout << nu2.
下面我们来看看是那里的问题:
注意你的第个参数,是按值传递的,也就是说在参数压栈的时候,会调用类的拷贝构造函数,你的原型如下:
    Cow(const Cow & c);
你的实现如下:
    strcpy(name,c.name);
    len=c.len;
    hobby=new char[len+1];
    strcpy(hobby,c.hobby);
    weight=c.weight;
请注意,对于拷贝构造函数的调用,你的实际参数是nu2,但你应该看看,当你按如语句定义nu2时,又做了什么:
    Cow nu2;
这会调用Cow默认的构造函数:
    Cow();
在你的实现中,你是这样做的:
    hobby=new char[1];
    hobby[0]='\0';
    strcpy(name,"no name");
    weight=0;
问题来了,注意,你没有对len初始化!所以在用nu2对象来构造cout<<nu2时,所产生的临时对象(调用上面你定义的拷贝构造函数)
    len=c.len;
    hobby=new char[len+1];
    strcpy(hobby,c.hobby);
这几句是有问题的,c.len,也就是nu2.len实际上并没有确定值!!在我的电脑上是
    -858993460
然后,你在动态分配内存,一个负值过去了...这其实还没有产生错误,只是hobby是等于null的,之后调用strcpy(hobby,c.hobby);按照strcpy的行为,它为将c.hobby中的内容拷贝到hobby中,直到c.hobby为'\0',然而hobby是没有空间的,这就造成了你的程序死掉了啊!!

不知道说清楚没有,如果只是调试程序,你可以将函数:
    friend ostream & operator<<(ostream & os,const Cow t);
写为:
    friend ostream & operator<<(ostream & os,const Cow& t);
注意是引用传递!没有临时对象的产生,当然也就不用调用你有问题的函数了,哈哈哈!


另外,你的程序问题多多,只是你没有遇到哈....共同努力!
2008-08-12 16:54
沿途有鬼
Rank: 1
等 级:新手上路
帖 子:68
专家分:0
注 册:2008-7-20
得分:0 
xlh5225 非常感谢你的详细解答啊,我是新手的确想不到你这么多我之前还以为就算没在Cow::Cow()中把len=4;赋值不会有什么问题顶多就是之不正确,现在知道不是了,看来我对构造函数到底调用的哪个不太清楚,感觉指针问题总在运行阶段出问题很难找出问题呀,你分析的真的很透彻,我自己感觉我学到了new分配的类这一块所编写的程序都会遇到运行终止的问题,看来我真的遇到技术瓶劲了,不过你的回答让我一下清楚了许多,非常感谢你的热心啊~!
2008-08-12 19:24
xlh5225
Rank: 2
等 级:论坛游民
威 望:2
帖 子:188
专家分:25
注 册:2007-8-14
得分:0 
我个人认为,动态内存分配是C++中,"最美"的东西之一...要掌握C++,这是必须要掌握的内容,建议一本书:Inside the C++ Object Model,讲的相当好,不过有点深,是C++的实现细节....共勉
2008-08-12 19:48
沿途有鬼
Rank: 1
等 级:新手上路
帖 子:68
专家分:0
注 册:2008-7-20
得分:0 
在main函数中,出错行是cout << nu2.

//cout<<nu2;  //这句崩了,因为nu2里的东西没被初始化,用了空指针了

我不知道如何用VC6.0调试找出上述语句的错误,请告诉我你是怎么知道的在这一句程序死掉的,为什么我用VC就查不到程序是在哪里死掉的,我不懂单步调试什么的怎么弄,请告诉我~谢谢啊~这对我找出错误很有帮助啊~!
2008-08-13 10:30
xlh5225
Rank: 2
等 级:论坛游民
威 望:2
帖 子:188
专家分:25
注 册:2007-8-14
得分:0 
VC有很好的调试工具,也就是DEBUG工具,内嵌在VC的IDE中了...
你可以设断点(F9,VC中是一个叹号标志),然后再调试执行,最后单步(F10)运行就行了...
2008-08-13 10:52



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-227879-1-1.html




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

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