【问题标题】:Self-made ugly vector自制的丑陋矢量
【发布时间】:2020-03-04 07:18:57
【问题描述】:

我有一些自编向量的训练示例,为了简单起见,它不是模板:

class UglyStringsVector {
public:
  UglyStringsVector() = default;
  explicit UglyStringsVector(size_t size);
  UglyStringsVector(const UglyStringsVector&);
  ~UglyStringsVector();

  std::string &operator[](size_t index);

  std::string *begin();
  std::string *end();

  const std::string *begin() const;
  const std::string *end() const;

  size_t Size() const;
  size_t Capacity() const;

  void PushBack(std::string value);
  void operator=(const UglyStringsVector &other);

private:
  std::string *data = nullptr;
  size_t size = 0;
  size_t capacity = 0;

  void ExpandIfNeeded();
};

赋值运算符没有正确实现:

UglyStringsVector& UglyStringsVector::operator=(const UglyStringsVector &other) {
  delete[] data;
  data = new std::string[other.capacity];
  size = other.size;
  capacity = other.capacity;
  copy(other.begin(), other.end(), begin());
  return *this;
}

正如我们在这里看到的,当this == &other我不是故意检查这个条件)时,它会删除自己的记忆(当然这是错误的),然后在同一个地方重新分配新的字符串(data = new std::string[other.capacity];),字符串不会未初始化,因为在operator new[]期间调用了默认构造函数,然后将字符串复制到自己(copy(other.begin(), other.end(), begin());)。

让我们想象一下失去记忆不是问题:-) 有人对我耳语说,将内存复制到自身是未定义的行为,但我不确定。 问题:是否有任何未定义的行为?

【问题讨论】:

标签: c++ new-operator undefined-behavior delete-operator assignment-operator


【解决方案1】:

假设data是一个有效的指针或nullptr,那么实际上根本没有UB。

使用new std::string[other.capacity],您可以创建default-initialized std::string 对象的“数组”。默认初始化(基本上默认构造)std::string 是一个有效但为空的字符串。

然后你将这个空字符串数组复制到它自己,这很好。


关于自复制,类似

int a = 0;
a = a;

这很奇怪,但很好。

【讨论】:

    【解决方案2】:

    没有任何未定义的行为。您只需删除数据指针指向的内存部分,然后重新分配一个新数组并将其分配给数据。

    【讨论】:

      猜你喜欢
      • 2018-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-06-11
      • 2014-01-16
      • 2014-06-21
      相关资源
      最近更新 更多