社区
C++ 语言
帖子详情
不检测自赋值的危险???
renheihei
2004-08-30 03:21:25
为什么在重载operator=时需要检测自赋值情况呢?
书上说是不检测的话很危险,能不能举例子说明??
...全文
335
11
打赏
收藏
不检测自赋值的危险???
为什么在重载operator=时需要检测自赋值情况呢? 书上说是不检测的话很危险,能不能举例子说明??
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
11 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
insulator
2004-08-31
打赏
举报
回复
class String
{
public:
String(const char *str = NULL); // 普通构造函数
String(const String &other); // 拷贝构造函数
~ String(void); // 析构函数
String & operate =(const String &other); // 赋值函数
private:
char *m_data; // 用于保存字符串
};
String & String::operate =(const String &other)
{
// (1) 检查自赋值
if(this == &other)
return *this;
// (2) 释放原有的内存资源
delete [] m_data;
// (3)分配新的内存资源,并复制内容
int length = strlen(other.m_data);
m_data = new char[length+1]; // 若能加 NULL 判断则更好
strcpy(m_data, other.m_data);
// (4)返回本对象的引用
return *this;
}
Paris_Luo
2004-08-31
打赏
举报
回复
hehe,的确,少写了一句.
短歌如风
2004-08-31
打赏
举报
回复
Paris_Luo的意思是这样:
String::operator=(const String& src)
{
//不检查自赋值,一般代码如下,先释放,后拷贝
delete[] data;
data = new char[strlen(str.data) + 1];//Paris_Luo少写了这一句
memcpy(data,src,strlen(str.data)+1); //自赋值时,拷贝一块已释放的内存!!
return *this;
}
在自赋值发生的时候,代码中的data和str.data其实是同一个,那么在第二句中就访问了在第一句中已经释放了的内存(strlen(str.data),str.data已经释放),这种操作是很危险的。
不过即使没有自赋值的问题,这段代码也有问题:
在data = new char...时是可能产生异常的,然后对象中的data将指向一段没有释放的内存,这个对象已经不能正常工作,甚至不能正常析构。如果在delete[]data之后加一句data = NULL虽然可以解决这个问题,但仍然不好——这样只是保证了对象能使用而没有保证对象状态,一个好的赋值操作符应该在产生异常时保持对象状态与未赋值前一样。正确的实现应该是:
String::operator=(const String& src)
{
char * newdata = NULL;
if (str.data != NULL)
{
newdata = new char[strlen(str.data) + 1];
strcpy(newdata, str.data);
}
delete[] data;
data = newdata;
return *this;
}
这个实现大家可以看到:即使自赋值发生了,仍然不会有问题,只不过做了一些不必要的操作罢了。所以Pari_Luo这个例子并不能说明问题,它在解决了异常安全问题之后就不存在自赋值问题了。
晨星
2004-08-31
打赏
举报
回复
To:楼上
Paris_Luo(不懂)不是都给出例子了吗?
comebaby
2004-08-31
打赏
举报
回复
用new会有怎么样的问题?
能不能举个例子
DiabloWalkOnTheEarth
2004-08-30
打赏
举报
回复
呵呵,我也是,一般非对外的接口的类我都 assert , 不过其他的还是判断一下为好
短歌如风
2004-08-30
打赏
举报
回复
我一般不检查自赋值,因为我觉得自赋值是一种很可笑的行为,所以都:
assert(this != &source);
renheihei
2004-08-30
打赏
举报
回复
楼上能不能举个例子?谢谢
ra3
2004-08-30
打赏
举报
回复
主要是对象中有用 new 分配动态内存的情况。
这时不检查自赋值就会出错,如果不用 new 应该不会有什么问题。
DiabloWalkOnTheEarth
2004-08-30
打赏
举报
回复
没什么,偶尔coredump而已
Paris_Luo
2004-08-30
打赏
举报
回复
如果成员有指针,而且该指针在重载operator=时,先释放,再拷贝的话,在自赋值时,就会出现问题
例如
class String
{
public:
String(const char*);
String(const String&);
String& oprator=(const String&);
private:
char *data;
};
String::operator=(const String& src)
{
//不检查自赋值,一般代码如下,先释放,后拷贝
delete[] data;
memcpy(data,src,strlen(str.data)+1); //自赋值时,拷贝一块已释放的内存!!
return *this;
}
void main()
{
String str1("hello");
str1 = str1; //错误!
}
PHP 运行时漏洞
检测
0x00 前言 这片博文将简单的介绍我编写的 PHP 运行时漏洞
检测
系统 prvd 的
检测
逻辑, 以及该系统在实际测试中的效果。 0x01 基本知识 在这里我们先介绍几个常用的词语: - source数据来源点,可以是: 网络,例如常规的 Web 参数等 文件系统 数据库 等等其他用户可控或者间接可控的地方 - filter数据过滤处理点,可以是: 编码解码,例如 base64_decode ...
别再让你的Verilog代码‘偷偷’生成Latch了!这4个坑我帮你踩过了
本文详细解析了Verilog设计中意外生成锁存器(Latch)的4个常见陷阱,包括不完整条件语句、自引用
赋值
等问题,并提供了实用的代码修复方案和预防策略,帮助FPGA工程师提升代码质量,避免时序和面积问题。
Verilog 组合逻辑设计中的锁存器陷阱:从if-else/case到敏感列表
本文深入探讨了Verilog组合逻辑设计中常见的锁存器陷阱,包括if-else/case语句不完整、敏感列表不全等问题。通过实际案例和代码示例,详细分析了锁存器的产生机制及其对电路设计的危害,并提供了避免意外生成锁存器的实用技巧和最佳实践。
Verilog新手避坑指南:为什么你的组合逻辑总偷偷生成Latch?
本文深入解析Verilog设计中意外生成锁存器(Latch)的常见陷阱,包括条件分支不完整、信号自引用和敏感列表缺失等问题。通过代码示例和检查清单,提供从预防到调试的完整解决方案,帮助开发者避免组合逻辑中的Latch隐患,提升数字电路设计质量。
C++ 语言
65,210
社区成员
250,514
社区内容
发帖
与我相关
我的任务
C++ 语言
C++ 语言相关问题讨论,技术干货分享,前沿动态等
复制链接
扫一扫
分享
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
请不要发布与C++技术无关的贴子
请不要发布与技术无关的招聘、广告的帖子
请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下
试试用AI创作助手写篇文章吧
+ 用AI写文章