Да, вы должны написать свой собственный. Это так просто, что это действительно глупо, но его производительность будет кричать по сравнению с просто используя таНос() и свободный() все время ....
static const int maxParticles = 1000;
static Particle particleBuf[maxParticles]; // global static array
static Particle* headParticle;
void initParticleAllocator()
{
Particle* p = particleBuf;
Particle* pEnd = &particleBuf[maxParticles-1];
// create a linked list of unallocated Particles
while (p!=pEnd)
{
*((Particle**)p) = p+1;
++p;
}
*((Particle**)p) = NULL; // terminate the end of the list
headParticle = particleBuf; // point 'head' at the 1st unalloc'ed one
}
Particle* ParticleAlloc()
{
// grab the next unalloc'ed Particle from the list
Particle* ret = headParticle;
if (ret)
headParticle = *(Particle**)ret;
return ret; // will return NULL if no more available
}
void ParticleFree(Particle* p)
{
// return p to the list of unalloc'ed Particles
*((Particle**)p) = headParticle;
headParticle = p;
}
Вы можете изменить подход выше не начать с какой-либо глобальной статический массив вообще, и сначала используйте malloc(), когда пользователь вызывает ParticleAlloc(), но когда возвращается Particles, не вызывайте free(), а вместо этого добавляйте возвращенные в связанный список неаллокуемых частиц. Затем следующий вызывающий элемент ParticleAlloc() получит один из списка свободных частиц, а не использует malloc(). Каждый раз, когда в свободном списке больше нет, ваша функция ParticleAlloc() может затем вернуться к malloc(). Или используйте сочетание двух стратегий, которые действительно были бы лучшими из обоих миров: если вы знаете, что ваш пользователь почти наверняка будет использовать по крайней мере 1000 частиц, но иногда может потребоваться больше, вы можете начать с статического массива 1000 и вернитесь на вызов malloc(), если закончите. Если вы это сделаете, для malloc() 'ed не требуется специальная обработка; просто добавьте их в свой список неаллектированных частиц, когда они вернутся к ParticleFree(). Вам не нужно беспокоиться о вызове free() на них, когда ваша программа завершается; операционная система освободит весь объем памяти процесса, так что всякая просочившаяся память исчезнет в этот момент.
Следует отметить, что, поскольку вы задали вопрос «C», а не «C++», я ответил на него в форме решения C. В C++ лучшим способом реализовать эту же задачу было бы добавить методы «operator new» и «operator delete» в ваш класс Particle. Они будут содержать в основном тот же код, что и выше, но они переопределяют (а не перегружают) глобальный «новый» оператор и, только для класса Particle, определяют специализированный распределитель, который заменяет глобальное «новое». Самое приятное, что пользователи объектов Particle даже не должны знать, что есть специальный распределитель; они просто используют «новое» и «удаляют» как обычно и остаются блаженно не осознающими, что их объекты Частицы исходят из специального заранее выделенного пула.
Не могли бы вы добавить определение для (struct?) Particle? Он содержит указатели? – wildplasser
+1. Насколько я знаю, C не делает то, что вы хотите. C++ делает это, используя синтаксис * места размещения *, который является забавным. Тем не менее, ничто не мешает вам выделять массив частиц (будь то в стеке или в куче), а затем по мере необходимости распределять хранилище для одной частицы. – thb
@thb: Я не думаю, что это новый сценарий размещения. OP хочет автоматическое управление памятью, но изолирован от определенной области памяти. –