C++析构成员失败

umbrook 2011-07-08 08:56:23
Hi,
跟踪代码,t1和t2的地址均不相同,各自的m_name的地址也不相同,但是在析构时系统报错:
_BLOCK_TYPE_IS_VALID,分不多,尽量给。

代码如下:

#include <iostream>
#include <string>
#include <list>
using namespace std;


class point
{
public:
point(int x,int y,char* name):m_x(x),m_y(y),m_name(name)
{

}
point(const point& p)
{
if (&p != NULL)
{
*this = p;
}

}
point& operator= (const point& instance)
{
if(this == &instance)
{
return *this;
}
this->m_x = 12211112;
this->m_y = 21212;
int size = strnlen(instance.m_name,100);
size = size > 0 ? size : 1;
this->m_name = new char[size+1];
strcpy(this->m_name,instance.m_name);
return *this;

}
virtual ~point()
{

if(NULL != m_name)
{
delete[] m_name;//当析构时,第二次delete报错。
m_name= 0;
}
}
public:
virtual float square() =0;
protected:
int m_x;
int m_y;
char* m_name;
};

class traple : public point
{
public:
traple(int x,int y,int z,char* name):point(x,y,name),m_z(z){}
public:
virtual float square()
{
return this->m_x * this->m_y * this->m_z;
}
char* GetName() const
{
return this->m_name;
}


protected:
int m_z ;
};

void main()
{
char str[10];
memset(str,0,sizeof(str));
strcpy(str,"B11111");
traple t1(1,2,78,str);
traple t3 = t1;

}
...全文
133 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
libingxuan13 2011-07-08
  • 打赏
  • 举报
回复
[Quote=引用 18 楼 babilife 的回复:]
引用 4 楼 bdmh 的回复:
你只在=操作符重载时 执行了一次 this->m_name = new char[size+1];但是析构可是两个啊,t1和t3,第一次已经delete了,第二次再delete必错



+1
[/Quote]
至善者善之敌 2011-07-08
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 bdmh 的回复:]
你只在=操作符重载时 执行了一次 this->m_name = new char[size+1];但是析构可是两个啊,t1和t3,第一次已经delete了,第二次再delete必错
[/Quote]


+1
umbrook 2011-07-08
  • 打赏
  • 举报
回复
TO : tujiaw
To : luciferisnotsatan
To : pengzhixi

十分感谢你们三位,你的指导对的,我想了一下,外面传入的
traple t1(1,2,78,"Bas") "Bas"是常量,属于栈上的,虽然用m_name(name),相当于m_name指向的是"Bas"。在做析构的时候,从下往上析构,先析构了t3,正确,然后析构t1的m_name,由于析构的m_name在栈上的,因此就错了。

最后十分感谢大家对我提问进行回答,谢谢。
luciferisnotsatan 2011-07-08
  • 打赏
  • 举报
回复
char* p = new char[3]; 
strcpy(p,"ab");
traple t1(1,2,78,p);


这么改
luciferisnotsatan 2011-07-08
  • 打赏
  • 举报
回复
[Quote=引用 9 楼 umbrook 的回复:]

我将调用的地方改成
char* p = new char[3];
p ="ab\0";
traple t1(1,2,78,p);


traple t1(1,2,78,"Bas");
同样报错,debug m_name的地址都不一样,不存在多次析构的问题,另外我查看vptr指向的是同一个地址,和这个有关系么?

引用 6 楼 luciferisnotsatan 的回复:
引……
[/Quote]

traple t1(1,2,78,"Bas");
"Bas"是字符串常量,在常量区里,也不用你释放。


char* p = new char[3]; // 虽然new了
p ="ab\0"; // 但你有把p指向了字符串常量,new出的空间泄漏了。另外,这不用显示加 \0,编译器自己会加
traple t1(1,2,78,p);
quwei197874 2011-07-08
  • 打赏
  • 举报
回复
要先delete一下自身,否则无法释放
umbrook 2011-07-08
  • 打赏
  • 举报
回复
debug下来,执行到traple t3 = t1;
会先去拷贝构造然后再调用operator =

[Quote=引用 10 楼 jaff20071234 的回复:]
traple t3 = t1; 直接调用拷贝构造而不是operator = 。
[/Quote]
ningto.com 2011-07-08
  • 打赏
  • 举报
回复
point(int x,int y,char* name):m_x(x),m_y(y),m_name(name)
m_name你这个不是在堆上分配的, 应该在构造函数里面new吧
umbrook 2011-07-08
  • 打赏
  • 举报
回复
我debug下来,t1的调用关系是
point(const point& p) 然后到point& operator=
t1的m_name在
这里初始化的
int size = strnlen(instance.m_name,100)+1;
this->m_name = new char[size];

[Quote=引用 7 楼 pengzhixi 的回复:]
引用 5 楼 umbrook 的回复:
会,拷贝构造函数会去执行我重载的operator=


引用 1 楼 pengzhixi 的回复:
额 你的t1的m_name是通过new分配的吗?你再看看


先看看再回答。而且你答非所问
[/Quote]
shawn 2011-07-08
  • 打赏
  • 举报
回复
traple t3 = t1; 直接调用拷贝构造而不是operator = 。
umbrook 2011-07-08
  • 打赏
  • 举报
回复
我将调用的地方改成
char* p = new char[3];
p ="ab\0";
traple t1(1,2,78,p);


traple t1(1,2,78,"Bas");
同样报错,debug m_name的地址都不一样,不存在多次析构的问题,另外我查看vptr指向的是同一个地址,和这个有关系么?

[Quote=引用 6 楼 luciferisnotsatan 的回复:]
引用 2 楼 umbrook 的回复:

问题补充,
1.析构的地方已经改成 delete[] m_name;问题如故。
2. this->m_x = 12211112; 这里是故意这样的做的。
this->m_y = 21212;
十分感谢。

有new 才 delete
有new[] 才 delete[]

str是栈上对象,不能delete
[/Quote]
luciferisnotsatan 2011-07-08
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 umbrook 的回复:]

会,拷贝构造函数会去执行我重载的operator=

引用 1 楼 pengzhixi 的回复:
额 你的t1的m_name是通过new分配的吗?你再看看
[/Quote]
问题是t1的m_name初始化,你是怎么做的?
point(int x,int y,char* name):m_x(x),m_y(y),m_name(name)
不是t3的
pengzhixi 2011-07-08
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 umbrook 的回复:]
会,拷贝构造函数会去执行我重载的operator=


引用 1 楼 pengzhixi 的回复:
额 你的t1的m_name是通过new分配的吗?你再看看
[/Quote]

先看看再回答。而且你答非所问
luciferisnotsatan 2011-07-08
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 umbrook 的回复:]

问题补充,
1.析构的地方已经改成 delete[] m_name;问题如故。
2. this->m_x = 12211112; 这里是故意这样的做的。
this->m_y = 21212;
十分感谢。
[/Quote]
有new 才 delete
有new[] 才 delete[]

str是栈上对象,不能delete
umbrook 2011-07-08
  • 打赏
  • 举报
回复
会,拷贝构造函数会去执行我重载的operator=

[Quote=引用 1 楼 pengzhixi 的回复:]
额 你的t1的m_name是通过new分配的吗?你再看看
[/Quote]
bdmh 2011-07-08
  • 打赏
  • 举报
回复
你只在=操作符重载时 执行了一次 this->m_name = new char[size+1];但是析构可是两个啊,t1和t3,第一次已经delete了,第二次再delete必错
luciferisnotsatan 2011-07-08
  • 打赏
  • 举报
回复
char str[10];
traple t1(1,2,78,str);
str是栈上对象,不用也不能delete
umbrook 2011-07-08
  • 打赏
  • 举报
回复
问题补充,
1.析构的地方已经改成 delete[] m_name;问题如故。
2. this->m_x = 12211112; 这里是故意这样的做的。
this->m_y = 21212;
十分感谢。
pengzhixi 2011-07-08
  • 打赏
  • 举报
回复
额 你的t1的m_name是通过new分配的吗?你再看看

64,647

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧