题目背景
基于自实现string类substr成员函数时遇到的问题。
代码展示
string string::substr(size_t pos, size_t len) //声明时len的参省值位npos
{
assert(pos < _size);
if (len > _size - pos) // 如果len的长度大于有效字符长度,那么重置为有效字符长度
{
len = _size - pos;
}
string arey;
arey.reserve(len);
for (int i = 0; i < len; ++i)
{
arey += _str[pos + i];
}
return arey;
}```
运行结果(仅在vs2019版本及以下会显现出来):
从这里,面试题就开始了。
面试提问
解释为什么会发生上述状况
从代码出发分析,substr函数的返回值为string,也就是传值返回,我们清楚地知道当传值返回一个类对象时会创建一个临时变量拷贝arey,再把arey拷贝给局部变量。
vs2019以及低版本地编译器在debug的优化下,会跳过创建临时变量,直接把arey拷贝给局部变量,那么既然substr的逻辑没有问题,那么问题是否是出现在拷贝构造函数?
调试发现,arat的地址和局部变量的地址是一样的,那么也就说明着,aray只是单纯的把_str中存储的字符串的地址传给了局部变量,而当substr调用完成后,_str又会被销毁,那么就会造成内存泄漏,从而引发上述状况。
这也就是所谓的浅拷贝。
解决问题
如何解决上述问题,那就是自己写一个显式拷贝构造函数。
拷贝构造函数代码
string(const string& s)
{
_str = new char[s._capacity + 1];
strcpy(_str, s._str);
_size = s._size;
_capacity = s._capacity;
}
至此,问题将得以解决。
注意
文中所展示的bug仅仅出现在低版本,优化不激进的情况下,若使用vs2019的release的情况下,也不会出现此状况。此时,编译器的优化更为激进,合三为一。
编译器直接构造给局部变量 !!!nb!
标签:面试题,string,len,c++,str,拷贝,size,arey From: https://blog.csdn.net/Moment124/article/details/140619247