社区
C++ 语言
帖子详情
不检测自赋值的危险???
renheihei
2004-08-30 03:21:25
为什么在重载operator=时需要检测自赋值情况呢?
书上说是不检测的话很危险,能不能举例子说明??
...全文
342
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 ...
C++移动语义误用详解:五大典型场景与避坑指南
移动语义是现代C++中用于优化资源管理、提升程序性能的核心机制,其本质是所有权的转移而非资源的简单复制。理解其底层原理对于编写高效、安全的代码至关重要,尤其在涉及动态内存、文件句柄等昂贵资源管理时,正确的移动操作能显著减少深拷贝开销。然而,误用移动语义可能导致数据损坏、悬空指针等难以调试的问题,严重影响软件稳定性与可维护性。本文聚焦于移动语义在实际工程中的应用陷阱,通过剖析返回局部变量、通用引用转发、移动后使用源对象等高频误用场景,结合C++11/14/17标准特性,提供系统的避坑指南与最佳实践,帮助开发者
C++
赋值
运算符重载:从浅拷贝陷阱到深拷贝实现与异常安全
在C++面向对象程序设计中,运算符重载是实现自定义类型行为的关键技术之一,它允许开发者赋予运算符新的含义,使其能作用于用户自定义的类对象。其核心原理是通过定义特殊的成员函数来重新解释运算符的行为,从而提升代码的直观性和可读性。这项技术的核心价值在于实现资源的正确管理与数据封装,是编写健壮、安全类的基石,尤其在涉及动态内存管理时至关重要。典型的应用场景包括实现自定义的字符串、容器或智能指针等资源管理类。本文将以一个自定义的`mystring`类为例,聚焦于**
赋值
运算符(operator=)**的重载,深入剖
C++拷贝
赋值
运算符深度解析:Copy-and-Swap与noexcept实战指南
在C++编程中,拷贝
赋值
运算符(operator=)是实现资源管理和对象复制的核心机制,其正确性直接影响程序的稳定性和性能。理解其工作原理需要从C++的RAII(资源获取即初始化)原则切入,它通过管理对象的生命周期来确保资源安全。传统实现常面临异常安全和自
赋值
等陷阱,而Copy-and-Swap惯用法通过结合拷贝构造函数和swap操作,在保证强异常安全的同时简化了代码逻辑。这一技术的工程价值在于,它能显著提升代码的健壮性,特别是在容器操作和资源管理类中。结合noexcept关键字,可以进一步优化移动语义下的
C++ 语言
65,212
社区成员
250,514
社区内容
发帖
与我相关
我的任务
C++ 语言
C++ 语言相关问题讨论,技术干货分享,前沿动态等
复制链接
扫一扫
分享
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++
技术论坛(原bbs)
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
请不要发布与C++技术无关的贴子
请不要发布与技术无关的招聘、广告的帖子
请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下
试试用AI创作助手写篇文章吧
+ 用AI写文章