讨论 一个有关构造函数和析构函数的问题??

xklc 易传媒 开发组长/高级工程师/技术专家  2002-10-11 03:06:02
我有一个程序,代码如下.
#include <iostream.h>
#include <string.h>

class Person
{
public:
Person()
{
}
Person(const Person &p)
{
pName = p.pName;
}
Person(char* pN)
{
cout << "Constructing " << pN << endl;
pName = new char[strlen(pN)+1];
if (pName != 0 )
{
strcpy(pName, pN);
}
}
~Person()
{
if(pName != NULL)
{
cout << "Destructing " << pName << endl;
delete pName;
pName = NULL;
}
}
protected:
char *pName;
};

void main()
{
Person p1("Randy");
Person p2(p1);
}
程序在退出后,输出结果本来应该是:
Constructing Randy
Destructing Randy
Destructing Randy
但是我在vc6.0(win2000平台)下调试,出现的结果却是内存报错.不知道什么原因,请各位指教
...全文
50 点赞 收藏 15
写回复
15 条回复
yitong111 2002年10月12日
if (pName != 0 )
{
strcpy(pName, pN);
pName[strlen(pN)+1]=NULL;
}
这样才行啊,你没有给字符串尾赋空值,当然会出现内存错误了
你要注意strlen不会给字符串尾自动加NULL的
回复 点赞
hello_wyq 2002年10月11日
这么多 的错误啊。

好好看书吧!

回复 点赞
bugfree 2002年10月11日

char *pName
改为
char pName[20];
回复 点赞
sandrowjw 2002年10月11日
默认的拷贝构造函数是二进制拷贝,由于你这里有指针,拷贝的时候把指针的值拷贝过去了,等于p1和p2的pNname指向同一个字符串,所以和原来的做法没有区别了。
回复 点赞
bugfree 2002年10月11日
没有给pName分内存
char *pName;
回复 点赞
blh 2002年10月11日
默认构造函数会创建一个块内存空间给新类,并且作一个类似memcpy的操作,将类的变量值进行复制,所以pName的指挥相同
回复 点赞
鸵鸟 2002年10月11日
#include <string.h>

class Person
{
public:
Person()
{
}
Person(const Person &p)
{
pName = p.pName; //error ,最好看看怎样写copy constructor
}
Person(char* pN)
{
cout << "Constructing " << pN << endl;
pName = new char[strlen(pN)+1];
if (pName != 0 )
{
strcpy(pName, pN);
}
}
~Person()
{
if(pName != NULL)
{
cout << "Destructing " << pName << endl;
delete pName; //error,用new [],动态分配的内存,请用delete []销毁.
pName = NULL;
}
}
protected:
char *pName;
};

void main()
{
Person p1("Randy");
Person p2(p1);
}
回复 点赞
xklc 2002年10月11日
To blh: 那为什么p2的pName为什么和p1的pName指向同一个地址呢.
回复 点赞
blh 2002年10月11日
默认构造函数有不会帮助你分配那个pName内存空间,回去好好看看c++的书再说
回复 点赞
LinuxPanther 2002年10月11日
是你的构造函数太简单了,让你的两个对象共享了一块内存,而在推出主函数是有调用两次析构函数,是你的第三次输出有错误可以改为:
#include<process.h>
class Person
{
...
Person(const Person &p)
{

pName = new char[strlen(p.pName)+1];
if (pName != 0 )
strcpy(pName, p.pName);
else
{
cout<<"Unseccess"<<endl;
exit(0);
}
cout<<"Person::copyconstructionfunction"<<pName<<endl;

}
........
};
回复 点赞
xklc 2002年10月11日
谢谢各位的解答,请看下面的程序,跟这个比较类似:
#include <iostream.h>
#include<string.h>

class Person
{
public:
Person(char* pN)
{
cout << "Constructing " << pN << endl;
pName = new char[strlen(pN)+1];
if (pName != 0 )
{
strcpy(pName, pN);
}

}
~Person()
{
cout << "Destructing " << pName << endl;
if(pName != NULL)
{
delete pName;
pName = NULL;
}
}
protected:
char *pName;
};

void main()
{
Person p1("Randy");
Person p2(p1);
}

本来我希望程序的运行结果是:
Constructing Randy
Destructing Randy
Destructing
但是依然是内存报错,本来, 在这部分中,没有拷贝构造函数,则应该调用默认的构造函数,因此当p2进行析构时,输出的结果应该是Destructing才对.但这里依然不对.请指教
回复 点赞
kof99th 2002年10月11日
楼上几位已经很清楚了。
使用指针一定要注意指针所指的内存空间,由谁分配,由谁释放,不难的。
回复 点赞
hhdsq 2002年10月11日
//下面这条语句出问题了
pName = p.pName;

经过这样的赋值以后,p1和p2的pName都指向同一块地址,在程序结束的时候析构了两次,当然会出错了。。

解决方法是利用strcpy,而不是用=来赋值
回复 点赞
blh 2002年10月11日
Person(const Person &p)
{
pName = p.pName; //这里的错误,这只是将p.pName和pName 指向同一块地址空间,并不是你本来认为的自动开辟一块新空间,呵呵,


if(pName != NULL)
{
cout << "Destructing " << pName << endl;
delete pName; //由于上面的错误,导致连续两次删除同一个地质,不错才怪呢,呵呵
pName = NULL;
}
回复 点赞
blue_coco 2002年10月11日
第二个构造函数有点问题。只是将指针付值,
相当于两个变量共用同一buffer.


Person()
{
pName = NULL
}
Person(const Person &p)
{
if (this == &p)
{
return;
}
if(NULL != pName)
{
delete pName;
}

pName = new char[strlen(p.pName)+1];
if (pName != 0 )
{
strcpy(pName, p.pName);
}
}

Person(char* pN)
{
cout << "Constructing " << pN << endl;
if(NULL != pName)
{
delete pName;
}

pName = new char[strlen(pN)+1];
if (pName != 0 )
{
strcpy(pName, pN);
}
}
回复 点赞
发动态
发帖子
C语言
创建于2007-09-28

3.2w+

社区成员

24.0w+

社区内容

C语言相关问题讨论
社区公告
暂无公告