销毁与销毁 [英] Destroy vs Deallocate

查看:90
本文介绍了销毁与销毁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Accelerated C ++的第11章中,作者提出了一个Vector类,该类使用数组模拟std :: vector的行为.他们使用分配器类来处理内存管理. uncreate函数的作用是破坏数组的每个元素并释放分配给该数组的空间:

In chapter 11 of Accelerated C++, the authors present a Vector class emulating the behaviour of std::vector using arrays. They use the allocator class to handle memory management. The role of the uncreate function is to destroy each element of the array and deallocate the space allocated for the array:

template <class T> void Vec<T>::uncreate() {
  if (data) {

  // destroy (in reverse order) the elements that were constructed 
  iterator it = avail;
  while (it != data)
    alloc.destroy(--it);

  // return all the space that was allocated
  alloc.deallocate(data, limit - data); 
  }

  // reset pointers to indicate that the Vec is empty again 
  data = limit = avail = 0;
}

显然,我们需要释放分配的空间.但是我不清楚我们为什么还需要销毁单个元素.如果仅释放内存而不破坏单个元素,将会发生什么?

Obviously we need to deallocate allocated space. But it's unclear to me why we need to destroy individual elements as well. What would happen if we only deallocated memory without destroying individual elements?

推荐答案

原因是它可能会给您带来麻烦. C ++标准第3.8章(对象生存期)的第4段解释了为什么(强调我的意思):

The reason is that it'd might get you in trouble. The paragraph 4 from chapter 3.8 (Object lifetime) of C++standard explains why (emphasis mine):

程序可以通过重用对象占用的存储空间或显式地结束任何对象的生命周期 为具有非平凡析构函数的类类型的对象调用析构函数.对于类类型的对象 如果使用非平凡的析构函数,则不需要程序在存储之前显式调用析构函数 对象占用的对象被重用或释放;但是,如果没有显式调用析构函数或 delete-expression(5.3.5)不用于释放存储,不应隐式调用析构函数,并且 任何依赖于析构函数产生的副作用的程序都具有未定义的行为.

A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor. For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.

这意味着可以在具有琐碎析构函数(*)的对象或根本没有一个对象的对象(例如ints等)占用的内存上执行此操作.但是,当内存中包含需要在析构函数中执行某些工作的类的对象(例如,关闭网络连接或文件,刷新缓冲区,释放内存)时,您将泄漏资源(按标准形式化,调用未定义的行为).

It means it's fine to do it on memory that's occupied by objects with trivial destructor(*) or objects that don't have one at all (such as ints and the like). But when the memory contains objects of a class that needs to do some work in the destructor (like closing network connections or files, flushing buffers, releasing memory), you'll leak resources (and formaly by the standard, invoke undefined behaviour).

(*)如果析构函数是编译器生成的,则析构函数不是虚拟的,并且它所属的所有非静态成员和直接基类都具有琐碎的析构函数.

(*) A destructor is trivial if it's compiler generated, is not virtual, and all the non-static members and direct base classes of the class it is member of have trivial destructors.

这篇关于销毁与销毁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆