Before I start my next plugin project I’m trying to collect as much info on DSP program efficiency & good coding technique.
Looking through the JUCE coding standards (awesome resource btw, thanks Jules!) I came across: “Do not ever use ‘new’ or malloc to allocate a C++ array. Always use a HeapBlock instead.”
I’ve sifted through many sites regarding HeapBlocks but I’m still quite not content with my understanding: What exactly is a HeapBlock & what is its advantage over using “new”?
In context, I’m trying to find the best way to create circular delay buffers, which in the past I’ve used “new” to do so.
That’s not really got anything to do with the preference for HeapBlock over new.
What you should look into (in answer to your specific question) is RAII.
The reason might be more clear if you instead think about it as preferring HeapBlock over delete/free. If you use a HeapBlock, then the deletion of the allocated memory is guaranteed when the object goes out of scope. All it really does is provide a robust and safe interface to manage and manipulate heap allocations - it’s not like it does anything particularly special. It means that you can never ‘forget’ to call free, because you never have to; any time that it should be called, it is.
It’s the same as with ScopedPointer - it’s not magic, it’s just a wrapper to a pointer that will make sure that the target object gets deleted if it is ever cleared or goes out of scope.
So yeah, look up RAII. You don’t need to use such constructs, but there’s not really much reason to avoid them, since all they actually do is make your life easier!
Below is a rough sketch of a circular delay buffer object in the works, with the intention of implementing RAII.
What would be the best way to declare the float array & set the pointer to it within the object’s constructor? I’m still squirrelly on the smart pointer syntax & the below code doesn’t work, although hopefully it’ll show what I’m trying to do.
[code]//Delay buffer using RAII paradigm #include
using namespace std;
class CDelayBuff
{
unique_ptr m_pBuff; //Points to array of floats
int m_iSize; //Stores size of float array
A thought just occurred to me after my last post: Since the array of floats is supposed to last as long as the CDelayBuff object itself, perhaps I could just use raw pointers within CDelayBuff (with the object’s destructor deleting the array) & then declare CDelayBuff objects in my parent plugin class using unique_ptr. The unique_ptr would then automatically call CDelayBuff’s destructor when it goes out of scope or if an exception is thrown. Would this be memory leak safe?
[code]class CDelayBuff1 //Using raw member pointers. unique_ptr is used to declare object in parent class
{
float* m_pBuff; //Points to array of floats
int m_iSize; //Stores size of float array
Thanks for all the help!! I think I’m really getting somewhere now & I found out how to add JUCE modules to non IntroJucer projects
I’m not sure if this is fundamentally possible in C++ structures, but in my delay class I’d like the user to have the ability to declare the number of channels via the object’s constructor (see code below). Thus, if the user declared: CPreDly PreDelay(2, 44100); , the object “PreDelay” would contain two Heapblocks, each with a size of 44100.
[code]#include "juce_core\JuceHeader.h"
using namespace std;
//PreDelay Module using RAII convention
//CONTAINS:
//Sample processing function (by reference)
//Cooking function (by reference)
//Smoothing function (by reference)
class CPreDly
{
int m_iSize; //Sample size for buffers
int m_iW; //Write index for delay buffers
OwnedArray<HeapBlock> m_DlyBuffs; //Array contaning delay buffers of each channel
CPreDly::CPreDly()
{
//OwnedArray & HeapBlock take care of memory deallocation
}
CPreDly::CPreDly(int &iNumChannels,int &iSize)
{
for (int i=0; i<iNumChannels; i++)
{
m_DlyBuffs.add(&(HeapBlock(iSize,true))); //Creates a HeapBlock of iSize floats and initializes them all to zero
}
m_iSize = iSize;
}[/code]