0

I have seen a class like this on the internet, the head file

#ifndef _COMMON_ARRAY_OBJECT_POOL_H_
#define _COMMON_ARRAY_OBJECT_POOL_H_

#include <stdint.h>

namespace easynet
{

class ArrayObjectPool
{
public:
    /** construct
     * @param elem_size : element size;
     * @param elem_num  : element number
     */
    ArrayObjectPool(uint32_t elem_size, uint32_t elem_num);
    ~ArrayObjectPool();

    uint32_t ElemSize(){return m_ElemSize;}
    uint32_t Capacity(){return m_ElemNum;}
    bool IsEmpty(){return m_FreeHead==NULL;}


    void* Get();


    bool Recycle(void *elem);
private:
    void *m_Elements;
    void *m_End;
    void *m_FreeHead;
    uint32_t m_ElemSize;
    uint32_t m_ElemNum;
};

}
#endif //_COMMON_ARRAY_OBJECT_POOL_H_

the cpp file

#include <assert.h>
#include <stddef.h>
#include <stdlib.h>

#include "ArrayObjectPool.h"

namespace easynet
{

ArrayObjectPool::ArrayObjectPool(uint32_t elem_size, uint32_t elem_num)
{
    m_ElemNum = elem_num;
    if(elem_size < sizeof(void*))
        m_ElemSize = sizeof(void*);
    else
        m_ElemSize = elem_size;

    m_Elements = malloc(m_ElemSize*m_ElemNum);
    m_End = (void*)((char*)m_Elements+m_ElemSize*m_ElemNum);
    assert(m_Elements != NULL);

    //construct list
    int i;
    void *node = m_Elements;
    for(i=0; i<m_ElemNum-1; ++i)
    {
        *(void**)node = (void*)((char*)node+m_ElemSize);
        node = *(void**)node;
    }
    *(void**)node = NULL;
    m_FreeHead = m_Elements;    //list head
}

ArrayObjectPool::~ArrayObjectPool()
{
    free(m_Elements);
}

void* ArrayObjectPool::Get()
{
    if(m_FreeHead == NULL)
        return NULL;
    void *temp = m_FreeHead;
    m_FreeHead = *(void**)m_FreeHead;
    return temp;
}

bool ArrayObjectPool::Recycle(void *elem)
{
    if(elem<m_Elements || elem>=m_End)
        return false;
    *(void**)elem = m_FreeHead;
    m_FreeHead = elem;
    return true;
}

}

The question is I can't understand what does this means:

int i;
void *node = m_Elements;
for(i=0; i<m_ElemNum-1; ++i)
{
*(void**)node = (void*)((char*)node+m_ElemSize);
node = *(void**)node;
}

and what the *(void**) means? thanks!

Prince
  • 20,353
  • 6
  • 39
  • 59
Ethan
  • 461
  • 4
  • 13

2 Answers2

2

It's treating the memory as if it were a union between the user's data type, and void*. When the blocks are in the free block list, the void* is used.

You can think of it as:

union ObjectInObjectPool
{
    void* ptr_next_free_block;
    UserType content;
};

and then that loop is basically doing:

ObjectInObjectPool* node = m_Elements;
for(i=0; i<m_ElemNum-1; ++i) {
    node->ptr_next_free_block = node + 1;
    node = node->ptr_next_free_block;
}

except that the programmer did by hand all the pointer arithmetic that the compiler's type checker usually does.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
0

A void* is a pointer value that points to untyped memory. When you do *(void**)node = ..., what it is really doing is *node = .... However, with the latter, you are trying to assign something to a void which doesn't make sense with C++'s type system; you have to do as in the former and cast it to a void** so that *node will be a void*, not a void, and you can assign to it.

node = *(void**)node is just node = *node but forcing the type system to work. It just does "assign to node the value of the memory at *node interpreted as a void*".

user3175411
  • 1,002
  • 7
  • 13
  • Thanks, I think I understand what the *(void**) means, but what the for loop's function? From my point, it doesn't do anything(*(void**)node = NULL; after for loop), during the for loop the node pointer plus a m_ElemSize range(eg: 4, 8, 12) every time. – Ethan Feb 08 '14 at 02:40