Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

basic_string.h:逻辑问题 #140

Open
initialjj opened this issue Nov 12, 2023 · 4 comments
Open

basic_string.h:逻辑问题 #140

initialjj opened this issue Nov 12, 2023 · 4 comments

Comments

@initialjj
Copy link

  • 在insert函数中
// 在 pos 处插入 n 个元素
template <class CharType, class CharTraits>
typename basic_string<CharType, CharTraits>::iterator
basic_string<CharType, CharTraits>::
insert(const_iterator pos, size_type count, value_type ch)
{
  iterator r = const_cast<iterator>(pos);
  if (count == 0)
    return r;
  if (cap_ - size_ < count)
  {
    return reallocate_and_fill(r, count, ch);
  }
  if (pos == end())
  {
    char_traits::fill(end(), ch, count);
    size_ += count;
    return r;
  }
  char_traits::move(r + count, r, count);
  char_traits::fill(r, ch, count);
  size_ += count;
  return r;
}

char_traits::move(r + count, r, count)应改为char_traits::move(r + count, r, end() - pos)

  • 同理
// 在 pos 处插入 [first, last) 内的元素
template <class CharType, class CharTraits>
template <class Iter>
typename basic_string<CharType, CharTraits>::iterator
basic_string<CharType, CharTraits>::
insert(const_iterator pos, Iter first, Iter last)
{
  iterator r = const_cast<iterator>(pos);
  const size_type len = mystl::distance(first, last);
  if (len == 0)
    return r;
  if (cap_ - size_ < len)
  {
    return reallocate_and_copy(r, first, last);
  }
  if (pos == end())
  {
    mystl::uninitialized_copy(first, last, end());
    size_ += len;
    return r;
  }
  char_traits::move(r + len, r, len);
  mystl::uninitialized_copy(first, last, r);
  size_ += len;
  return r;
}

char_traits::move(r + len, r, len)应改为char_traits::move(r + len, r, end() - pos)

@myc13381
Copy link

对于字符串move函数定义如下

  // 字符串移动(复制),允许复制的两个地址段有重复,具体操作是更具源地址和目的地址关系选择从前后复制还是从后向前复制
  static char_type* move(char_type* dst, const char_type* src, size_t n)
  {
    char_type* r = dst;
    if (dst < src)
    {
      for (; n != 0; --n, ++dst, ++src)
        *dst = *src;
    }
    else if (src < dst)
    {
      dst += n;
      src += n;
      for (; n != 0; --n)
        *--dst = *--src;
    }
    return r;
  }

最后一个参数n的类型是size_t类型,这里使用count作为移动字符的数目应该没有问题

@initialjj
Copy link
Author

对于字符串move函数定义如下

  // 字符串移动(复制),允许复制的两个地址段有重复,具体操作是更具源地址和目的地址关系选择从前后复制还是从后向前复制
  static char_type* move(char_type* dst, const char_type* src, size_t n)
  {
    char_type* r = dst;
    if (dst < src)
    {
      for (; n != 0; --n, ++dst, ++src)
        *dst = *src;
    }
    else if (src < dst)
    {
      dst += n;
      src += n;
      for (; n != 0; --n)
        *--dst = *--src;
    }
    return r;
  }

最后一个参数n的类型是size_t类型,这里使用count作为移动字符的数目应该没有问题

移动字符的数目就有问题,应该是先把pos到end()这一段往后移动count,再把[first, last)拷贝进来,所以移动数目是end()-pos,对应dst是r+count,src是r。

@myc13381
Copy link

我看了一下,确实如此,如果move第三个参数传递count,可能会导致某些值被覆盖而不是被移动,这逻辑确实有问题,还是等作者回复吧

@jsuwcp
Copy link

jsuwcp commented Jan 22, 2024

是不是应该先将first到last之间的元素拷贝下来,在移动,因为移动可能改变了first和last指向的元素位置或者basic_string重新分配了内存

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants