简体   繁体   English

动态数组取消分配(赋值运算符与副本构造函数)

[英]Dynamic array deallocation (assignment operator vs. copy constructor)

Should i deallocate dynamic array (allocated in constructor) in copy constructor and/or assignment operator? 我应该在复制构造函数和/或赋值运算符中释放动态数组(在构造函数中分配)吗?

struct Test
{
  const size_t n;
  int* xs;

  Test(const size_t n)
    : n(n)
    , xs(new int[n])
  { }

  Test(const Test& other)
    : n(other.n)
    , xs(new int[n])
  {
    memcpy(xs, other.xs, n * sizeof(int));
  }

  Test& operator=(const Test& other)
  {
    n = other.n;
    delete[] xs;
    xs = new int[n];
    memcpy(xs, other.xs, n * sizeof(int));
  }

  ~Test()
  {
    delete[] xs;
  }
};

void main()
{
  Test a(10);
  Test b(a);
  Test c(20);
  c = b;
}

As you can see, I guess that you have to delete[] the array in assignment operator implementation (since it has been already allocated somewhere during construction of the object that's being assigned to). 如您所见,我猜您必须在赋值运算符实现中delete[]数组(因为在构造要分配给的对象的过程中已经将该数组分配到了某个位置)。 And I do think that you don't need to deallocate the array while copy constructing the object, since it has not been constructed yet. 而且我确实认为,在复制构造对象时不需要释放数组,因为尚未构造该对象。

The thing is, running the application above under Application Verifier shows no memory leaks no matter if there is delete[] in operator= or if there is not. 问题是,无论是否在operator= delete[] ,在Application Verifier下运行以上应用程序都不会显示内存泄漏。 Application runs OK though in both cases. 尽管在两种情况下,应用程序都可以正常运行。

So, should I delete[] xs in copy constructor, assignment operator, both or neither? 所以,我应该在复制构造函数,赋值运算符中都delete[] xs还是两者都不做?

In general, manual memory management is a bad idea. 通常,手动内存管理是一个主意。 You shouldn't do it, and you should prefer std::vector<> or other container classes, unless you have a good reason for doing otherwise. 您不应该这样做,并且您应该更喜欢std::vector<>或其他容器类,除非您有充分的理由这样做。 This said... 说...

So, should I delete[] xs in copy constructor, assignment operator, both or neither? 所以,我应该在复制构造函数,赋值运算符中都删除[] xs还是两者都不做?

You should delete[] an array allocated with new[] before you lose the last pointer to that array. 在丢失指向该数组的最后一个指针之前,应delete[]一个分配有new[]数组。 Otherwise, you will leak. 否则,您将泄漏。

In practice, since the array you want to delete is owned and encapsulated by your class, this means that you will have to delete[] it in the assignment operator overload (before the pointer gets assigned to a new array, thus losing the only existing reference to the previous one) and in the destructor (when you are disposing of the object and then losing the only existing reference to the encapsulated array). 实际上,由于您要删除的数组是由您的类拥有并封装的,因此这意味着您必须在赋值运算符重载中将delete[] (在将指针分配给新数组之前,因此将丢失唯一的现有数组)对前一个引用)和在析构函数中(当您处置该对象,然后丢失对封装数组的唯一现有引用时)。

As you say, the copy constructor is a construction routine and the pointer wasn't previously referencing any allocated resource (in fact, there is no "previously" here, the object's lifetime hasn't even begun): therefore, it is not only not needed to delete[] here, it is wrong. 就像您说的那样,复制构造函数是一个构造例程,并且指针先前未引用任何已分配的资源(实际上,这里没有“以前”,对象的生命期甚至还没有开始):因此,不仅这里不需要delete[] ,这是错误的。

Also notice, that in order to avoid dangling pointers and possible undefined behavior, you should make sure that your class is indeed the only owner of the encapsulated array. 还要注意,为了避免悬空的指针和可能的未定义行为,您应确保您的类确实是封装数组的唯一所有者。 Otherwise, code external to the class could delete[] it, or save pointers to it that will become dangling. 否则,该类外部的代码可以delete[] ,或保存指向该类的指针,这些指针将变得悬而未决。 Thus, you should not make the xs data member public . 因此,您不应将xs数据成员xs public

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM