项目场景:
string类中insert的模拟实现
问题描述:
当我用下面这种方法进行插入的时候,会出现一个死循环,
string& insert(size_t pos, char ch)
{
assert(pos <= _size);
if (_size == _capacity)
reserve(_capacity==0?4:_capacity*2);
size_t end = _size;
while (end >= pos)
{
if (end == 0)
{
cout << end << endl;
}
_str[end + 1] = _str[end];
--end;
}
_str[++end] = ch;
_size++;
return *this;
}
void testinsert()
{
string s1("hello world");
s1.insert(0, 'z');
cout << s1.c_str() << endl;
}
原因分析:
1.因为在函数insert中,end是用size_t定义的,所以当end–直到0 的时候,赋值后会再进行一次-- ,那么end变为-1,而end是一个无符号型的类型,所以,-1即为最大值(4294967290),所以会一直循环下去。
2.即使将end定义为是int的类型,C代码在遇到不同数据类型不一致的情况下,会自动进行类型提升。也就是说en还是会被提升成size_t,类型提升的规则如下:
如果两种类型字节数不同,则转换成字节数高的类型。
如果两种类型字节数相同,但一种有符号,一种无符号,则转换成无符号类型
所有浮点都是以双精度类型进行的,即使只含有单精度运算的表达式,也要先转换成double型,再作运算。
解决方案:
1.将end改为int,并且将pos强制转换成int;
2.换一种写法,如下:
string& insert(size_t pos, char ch)
{
assert(pos <= _size);
if (_size == _capacity)
reserve(_capacity==0?4:_capacity*2);
size_t end = _size+1;//从后往前插的时候,end的开始位置是最后一个元素的'\0'后一位,这样代码写起来比较方便
while (end >pos)
{
_str[end] = _str[end-1];
end--;
}
_str[++end] = ch;
_size++;
return *this;
}