社区
C++ 语言
帖子详情
不检测自赋值的危险???
renheihei
2004-08-30 03:21:25
为什么在重载operator=时需要检测自赋值情况呢?
书上说是不检测的话很危险,能不能举例子说明??
...全文
334
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 运行时漏洞
检测
本文介绍了一个名为prvd的PHP运行时漏洞
检测
系统,它利用PHP扩展xmark进行源数据标记和函数hook,实现了taint模式和payload模式来
检测
潜在的安全问题。prvd在实际测试中能有效发现SQL注入、 SSRF等漏洞,同时通过Sentry作为漏洞上报平台。
别再让你的Verilog代码‘偷偷’生成Latch了!这4个坑我帮你踩过了
本文深入剖析Verilog设计中意外生成锁存器(Latch)的四大核心原因:不完整if-else/case语句、自引用
赋值
、敏感列表不全,并给出综合工具配置、静态代码检查(如Verilator)、单元测试等预防策略。重点聚焦FPGA数字电路设计中的Latch规避方法,涵盖Xilinx Vivado与Intel Quartus平台实操要点及RTL级验证手段。
Verilog 组合逻辑设计中的锁存器陷阱:从if-else/case到敏感列表
本文深入剖析Verilog组合逻辑设计中意外生成锁存器的四大成因:不完整if-else分支、缺失default的case语句、自引用
赋值
及敏感列表遗漏。阐述锁存器的透明性、记忆性和异步性特征,及其引发的毛刺敏感、资源浪费和时序分析困难等问题,并提供RTL级
检测
方法与规避策略。
Verilog新手避坑指南:为什么你的组合逻辑总偷偷生成Latch?
本文深入剖析Verilog中因条件分支不完整、信号自引用及敏感列表缺失等常见编码错误导致意外锁存器生成的原理与风险,涵盖锁存器对时序收敛、面积功耗及亚稳态的影响,并提供代码规范检查、综合工具告警分析、RTL视图定位等系统性预防与调试方法。
C++ 语言
65,211
社区成员
250,515
社区内容
发帖
与我相关
我的任务
C++ 语言
C++ 语言相关问题讨论,技术干货分享,前沿动态等
复制链接
扫一扫
分享
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
请不要发布与C++技术无关的贴子
请不要发布与技术无关的招聘、广告的帖子
请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下
试试用AI创作助手写篇文章吧
+ 用AI写文章