在上一篇的内存管理简单实例中,我们用一个 next 指针将分配的一整块内存中的每个对象大小的内存块链接成链表,客户端需要动态分配对象内存时,直接从链表上获取,减少了不必要的 cookie 内存消耗。但是缺点也很明显,就是增加了每个对象的 next 指针的内存消耗。我们可以看看什么时候会使用到 next 指针:
- 当分配了一大块内存,这一大块内存上的每个对象大小的小内存块需要用 next 指针串在一起,注意,此时内存块对于客户端来说处于为分配状态,也就是客户端并没有使用这块内存。
- 当客户端使用 new 申请分配一块内存时,将从事先分配好的内存链表上取出一小块,分配给客户端使用。注意,客户端使用时,next 数组将不再被使用。
- 当客户端使用 delete 将对象内存回收时,这块内存将会被再次插入到链表上。注意,此时又会重新使用 next 指针,串接到链表上。
以上的分析可以看出,当分配内存和回收内存的时候,才会去使用到 next 指针,当该内存被分配给客户端使用时,该 next 指针将不在被使用到。也就是说, 对象本身的数据内存和 next 指针的数据内存不会同时被使用。因此,我们可以将对象本身的数据和 next 指针的数据共用同一个内存。于是就使用到了 union 数据类型。 这种类型的指针被称为 embeded pointer
看如下代码:
class Airplane
{
private:
struct AirplaneRep
{
unsigned long miles;
char type;
};
union
{
AirplaneRep rep; //针对使用中的 object,以 AirplaneRep 类型去解释内存数据
Airplane *next; //针对 freelist 上的 object,以指针形式解释内存数据
};
public: