@LokiAstari is right, you clearly have a problem with your pointers on resize.
There's something I don't understand; you say you're using an object pool but that you have problems with too many new statements. If you're using an object pool, I would say it's precisely to avoid new statements, no?
Here are my suggestions, although I'm no expert and there might be better solutions involving the implementation of your own allocator typically (dark side of the force..). You could use a container like std::deque
, which ensures the validity of pointers/references on resize.
You would begin with an initial resize of a lot of Objects (your pool), and you can either handle manually the subsequent resize when needed (extending the capacity with chunks of predefined size), or accept the new statements then if you know there shouldn't be a lot, and use the emplace_back method.
I also don't know if you're doing a lot of insertion/deletion of objects with your IDs. If so, you might consider using std::unordered_map
.
Here is an example using std::deque
:
#include <iostream>
#include <deque>
#define POOL_RESERVE 1000
// Data storage for your object
struct MyObjectData
{
double some_data;
};
// Container returned by the factory
struct MyObject
{
typedef MyObjectData data_type;
unsigned id;
data_type* data;
MyObject(): id(0), data(0) {}
MyObject( const unsigned& id_, data_type* data_ ): id(id_), data(data_) {}
void set( const unsigned& id_, data_type* data_ )
{ id = id_; data = data_; }
};
// MyObject Pool
class MyObjectPool
{
public:
typedef MyObjectData data_type;
MyObjectPool(): count(0) { pool.resize(POOL_RESERVE); }
void get( const unsigned& id, MyObject& obj )
{
// Check requested index
if ( id >= count )
obj.set( 0, 0 );
else
obj.set( id, &pool[id] );
}
void create( MyObject& obj )
{
// Create new data container if needed
if ( count++ >= pool.size() ) pool.emplace_back();
// Return next available object
obj.set( count-1, &pool[count-1] );
}
private:
unsigned count;
std::deque<data_type> pool;
};
// MyObject factory
class MyObjectFactory
{
typedef MyObjectFactory self;
static MyObject local;
static MyObjectPool& get_instance()
{
static MyObjectPool pool;
return pool;
}
public:
static MyObject get( const unsigned& id )
{
self::get_instance().get(id,local);
return local;
}
static MyObject create()
{
self::get_instance().create(local);
return local;
}
};
// Define static variable
MyObject MyObjectFactory::local = MyObject();
// Usage example
int main()
{
MyObject a,b,c;
a = MyObjectFactory::create();
b = MyObjectFactory::create();
c = MyObjectFactory::get(1);
}