checked_delete/checked_array_delete

  在boost的智能指针中析构时都用到了checked_delete 和checked_array_delete,为什么不简单地delete呢?

  在头文件”boost/checked_delete.hpp”定义了两个函数模板,checked_delete 和 checked_array_delete, 以及两个类模板,checked_deleter 和 checked_array_deleter。他们作用是什么呢?

官方解释:

  C++标准的 5.3.5/5 节中允许通过一个 delete 表达式删除指向不完全类的指针。如果该类有一个非平凡的析构函数,或者有一个类相关的 delete 操作符,那么其行为就是无定义的。有些编译器会在删除不完全类型时给出警告,但不幸的是,不是所有编译器都这样,而且程序员有时也会忽略或禁止警告。

  一个尤其麻烦的情况是以一个不完全类型实例化一人智能指针的析构函数,如 boost::scoped_ptr::~scoped_ptr。这通常会引起难以跟踪的错误。

  本库提供的函数和类模板可用于防止这些问题,它们要求一个完全的类型,否则引发一个编译错误。

  如果T是Incomplete Types,sizeof(T)将返回0,此时checked_delete将因为声明-1个成员的数组而引发错误。

  什么是Incomplete Types?

  An incomplete type is a type that describes an identifier but lacks information needed to determine the size of the identifier. An “incomplete type” can be:

  A structure type whose members you have not yet specified.

  A union type whose members you have not yet specified.

  An array type whose dimension you have not yet specified.

  The void type is an incomplete type that cannot be completed. To complete an incomplete type, specify the missing information. The following examples show how to create and complete the incomplete types.

struct student;      // incomplete type
struct student
{
    int num;
}                 // student structure now completed 

int a[];            // incomplete type
int a[20];          // now completed

  checked_delete和checked_array_delete代码如下:

template<class T> inline void checked_delete(T * x)
{
  typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
  (void) sizeof(type_must_be_complete);
  delete x;
}

template<class T> inline void checked_array_delete(T * x)
{
  typedef char type_must_be_complete[ sizeof(T)? 1: -1 ];
  (void) sizeof(type_must_be_complete);
  delete [] x;
}

  来看stackoverflow上的一个例子:

  The most common example of an incomplete type is one that has only been declared:

// this file does not include the definition of foo
class foo;
void bad(foo *f)
{
    delete f;  // undefined behavior if there exists foo::~foo
}

  In reality, the definition of foo may look like this:

class foo
{
public:
    ~foo() { ... };
};

  But if the top code has not ‘seen’ the class definition and just sees the class declaration, the code will compile.

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-08 21:19:12

checked_delete/checked_array_delete的相关文章

Boost 1.61.0 Library Documentation

http://www.boost.org/doc/libs/1_61_0/ Boost 1.61.0 Library Documentation Accumulators Framework for incremental calculation, and collection of statistical accumulators. Author(s): Eric Niebler First Release: 1.36.0 Standard: Categories: Math and nume

boost::checked_delete

先看一段能够正常执行的代码,但会造成内存泄漏: deleteObject.h 实现删除一个CObjectItem的派生类的指针所指的内存 #pragma once namespace smtlCheck { class CObjectItem; class CDeleteObject { public: CDeleteObject(void); ~CDeleteObject(void); void deleteObject(CObjectItem *vObj); }; } deleteObjec

Boost源码学习---

scoped_array功能类似scoped_ptr,scoped_array管理的是new[]开辟的数组,其析构函数调用的是delete[]释放数组. 它没有重载解引用*和箭头操作符->,因为它不是普通指针,而是一个数组.它重载了[],可以像使用数组下标那样访问数组. #ifndef BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED #define BOOST_SMART_PTR_SCOPED_ARRAY_HPP_INCLUDED // (C) Copyrig

关键字:__thread &amp; pthread_key_t

在说__thread之前,先来看看pthread_ket_t吧. 参考:http://blog.csdn.net/lmh12506/article/details/8452700 上面的博文说的比较通俗易懂.线程私有数据可以理解为线程内的全局变量.在线程内可以被所有函数访问,但是不能被其他线程的函数访问. 这里博主直接去找pthread.h头文件中的API,发现写的还是很详细的. /* Functions for handling thread-specific data. */ //用于处理线

shared_array

1.上次写的删除器有些问题: template<class P, class D> class sp_counted_impl_pd : public sp_counted_base{ public:     sp_counted_impl_pd(P p, D d) : ptr(p), del(d){} public:     void dispose(){         del(ptr);  //就是这里,将对象用作函数!!!     } private:     P ptr;     D

weak_ptr和intrusive_ptr

1.weak_ptr (1).weak_ptr是为了配合shared_ptr而引入的智能指针,它更像是shared_ptr的一个助手,它不具有普通指针的行为, 没有重载operator*和->,它的最大作用在于协助shared_ptr工作,像旁观者那样观测资源的使用情况. (2).2个重要接口:bool expired()const :// 判断是否过期 lock()函数是弱指针的核心: (3).获得资源的观测权,但weak_ptr没有共享资源,它的构造不会引起引用计数的增加,它的析构也不会导致

所有的 Boost 库文档的索引

按字母顺序列出的库 按类别列出的库 算法 破碎的编译器的解决方法 并发编程 容器 正确性和测试 数据结构 特定于域的 函数对象和高阶编程 泛型编程 图像处理 输入/输出 跨语言支持 迭代器 语言功能仿真 数学和数字 内存 解析 模式和习语 预处理器元编程 编程接口 状态机 字符串和文本处理 系统 模板元编程 杂项 图书馆从提高退休 请参阅入门页面以了解如何下载. 构建和安装库. 按字母顺序列出的库 蓄能器-增量计算和统计累加器,Eric Niebler 从集合框架 算法-有用的通用算法,从马歇尔

Boost源码学习---scoped_ptr.hpp

scoped_ptr是一个智能指针,包装了指向堆上内存的指针.它对指针所有权加以限制,不能转让指针所有权,一旦scoped_ptr获取了指针的管理权,便不再释放,无法再从其取回来,就像scope意思一样,指针智能在作用域使用,不能转让出去.一旦离开scoped_ptr的作用域,将调用它的析构函数,释放指针,不用手动释放.下面是它的源代码: #ifndef BOOST_SMART_PTR_SCOPED_PTR_HPP_INCLUDED #define BOOST_SMART_PTR_SCOPED_

Chapter 10-01

Please indicate the source: http://blog.csdn.net/gaoxiangnumber1 Welcome to my github: https://github.com/gaoxiangnumber1 ?C++语言的三大约束是:与C兼容.零开销(zero overhead)原则.值语义.§11.7介绍值语义. ?"与C兼容"不仅仅是兼容C的语法,更重要的是兼容C语言的编译模型与运行模型,也就是说能直接使用C语言的头文件和库. ?比方说对于con