From cdc53f1ed8596a5e448e4820021f4d0e1360039f Mon Sep 17 00:00:00 2001 From: Dennis Scheiba Date: Wed, 28 Jan 2026 23:24:45 +0100 Subject: [PATCH 1/3] fix RTAlloc of FaustClass in SuperCollider --- architecture/supercollider.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/architecture/supercollider.cpp b/architecture/supercollider.cpp index e5b9f39131..67379bfee6 100644 --- a/architecture/supercollider.cpp +++ b/architecture/supercollider.cpp @@ -493,11 +493,12 @@ void Faust_next_clear(Faust* unit, int inNumSamples) void Faust_Ctor(Faust* unit) // module constructor { // Allocate DSP - unit->mDSP = new(RTAlloc(unit->mWorld, sizeof(FAUSTCLASS))) FAUSTCLASS(); - if (!unit->mDSP) { + void* mem = RTAlloc(unit->mWorld, sizeof(FAUSTCLASS)); + if(mem == nullptr) { Print("Faust[%s]: RT memory allocation failed, try increasing the real-time memory size in the server options\n", g_unitName); goto end; } + unit->mDSP = new(mem) FAUSTCLASS(); { // Possibly call classInit again if (SAMPLERATE != g_sampleRate) { From c86a35b387966f5f212cc81e835b626aee8de232 Mon Sep 17 00:00:00 2001 From: Dennis Scheiba Date: Thu, 29 Jan 2026 00:26:20 +0100 Subject: [PATCH 2/3] fix memory leak in case allocation fails --- architecture/supercollider.cpp | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/architecture/supercollider.cpp b/architecture/supercollider.cpp index 67379bfee6..4f9fbaec49 100644 --- a/architecture/supercollider.cpp +++ b/architecture/supercollider.cpp @@ -492,10 +492,14 @@ void Faust_next_clear(Faust* unit, int inNumSamples) void Faust_Ctor(Faust* unit) // module constructor { + // init such that we can use generic end goto + unit->mDSP = nullptr; + unit->mInBufCopy = nullptr; + unit->mInBufValue = nullptr; + // Allocate DSP void* mem = RTAlloc(unit->mWorld, sizeof(FAUSTCLASS)); if(mem == nullptr) { - Print("Faust[%s]: RT memory allocation failed, try increasing the real-time memory size in the server options\n", g_unitName); goto end; } unit->mDSP = new(mem) FAUSTCLASS(); @@ -552,7 +556,6 @@ void Faust_Ctor(Faust* unit) // module constructor } else { unit->mInBufCopy = (float**)RTAlloc(unit->mWorld, unit->mDSP->getNumInputs()*sizeof(float*)); if (!unit->mInBufCopy) { - Print("Faust[%s]: RT memory allocation failed, try increasing the real-time memory size in the server options\n", g_unitName); goto end; } // Allocate memory for input buffer copies (numInputs * bufLength) @@ -560,13 +563,11 @@ void Faust_Ctor(Faust* unit) // module constructor // = numInputs * (bufLength + 1) unit->mInBufValue = (float*)RTAlloc(unit->mWorld, unit->mDSP->getNumInputs()*sizeof(float)); if (!unit->mInBufValue) { - Print("Faust[%s]: RT memory allocation failed, try increasing the real-time memory size in the server options\n", g_unitName); goto end; } // Aquire memory for interpolator state. float* mem = (float*)RTAlloc(unit->mWorld, unit->mDSP->getNumInputs()*BUFLENGTH*sizeof(float)); if (mem) { - Print("Faust[%s]: RT memory allocation failed, try increasing the real-time memory size in the server options\n", g_unitName); goto end; } for (int i = 0; i < unit->mDSP->getNumInputs(); ++i) { @@ -599,6 +600,10 @@ void Faust_Ctor(Faust* unit) // module constructor } end: + Print("Faust[%s]: RT memory allocation failed, try increasing the real-time memory size in the server options\n", g_unitName); + RTFree(unit->mWorld, unit->mDSP); + RTFree(unit->mWorld, unit->mInBufCopy); + RTFree(unit->mWorld, unit->mInBufValue); // Fix for https://github.com/grame-cncm/faust/issues/13 ClearUnitOutputs(unit, 1); } From da56147ed01767acb5f55d8548ba808281e6732d Mon Sep 17 00:00:00 2001 From: Dennis Scheiba Date: Fri, 30 Jan 2026 14:29:12 +0100 Subject: [PATCH 3/3] replace goto end with ClearUnitIfMemFailed --- architecture/supercollider.cpp | 33 ++++++++++++--------------------- 1 file changed, 12 insertions(+), 21 deletions(-) diff --git a/architecture/supercollider.cpp b/architecture/supercollider.cpp index 4f9fbaec49..0301335b16 100644 --- a/architecture/supercollider.cpp +++ b/architecture/supercollider.cpp @@ -492,16 +492,16 @@ void Faust_next_clear(Faust* unit, int inNumSamples) void Faust_Ctor(Faust* unit) // module constructor { - // init such that we can use generic end goto + // init such that those values can be freed if any alloc fails unit->mDSP = nullptr; unit->mInBufCopy = nullptr; unit->mInBufValue = nullptr; + unit->mControlInputs = nullptr; + unit->mControlOutputs = nullptr; // Allocate DSP void* mem = RTAlloc(unit->mWorld, sizeof(FAUSTCLASS)); - if(mem == nullptr) { - goto end; - } + ClearUnitIfMemFailed(mem); unit->mDSP = new(mem) FAUSTCLASS(); { // Possibly call classInit again @@ -518,8 +518,6 @@ void Faust_Ctor(Faust* unit) // module constructor ControlAllocator ca(unit->mControls); unit->mDSP->buildUserInterface(&ca); - unit->mInBufCopy = nullptr; - unit->mInBufValue = nullptr; #ifdef SOUNDFILE // Access soundfiles @@ -534,7 +532,9 @@ void Faust_Ctor(Faust* unit) // module constructor // Build mControlInputs and mControlOutputs so that getInputControl/getOutputControl have O[1] cost unit->mControlInputs = (Control**)RTAlloc(unit->mWorld, unit->mNumControlInput*sizeof(Control*)); + ClearUnitIfMemFailed(unit->mControlInputs); unit->mControlOutputs = (Control**)RTAlloc(unit->mWorld, unit->mNumControlOutput*sizeof(Control*)); + ClearUnitIfMemFailed(unit->mControlOutputs); for (int i = 0; i < unit->mNumControlInput; ++i) { unit->mControlInputs[i] = unit->getInputControlAux(i); @@ -555,21 +555,15 @@ void Faust_Ctor(Faust* unit) // module constructor SETCALC(Faust_next); } else { unit->mInBufCopy = (float**)RTAlloc(unit->mWorld, unit->mDSP->getNumInputs()*sizeof(float*)); - if (!unit->mInBufCopy) { - goto end; - } + ClearUnitIfMemFailed(unit->mInBufCopy); // Allocate memory for input buffer copies (numInputs * bufLength) // and linear interpolation state (numInputs) // = numInputs * (bufLength + 1) unit->mInBufValue = (float*)RTAlloc(unit->mWorld, unit->mDSP->getNumInputs()*sizeof(float)); - if (!unit->mInBufValue) { - goto end; - } + ClearUnitIfMemFailed(unit->mInBufValue); // Aquire memory for interpolator state. float* mem = (float*)RTAlloc(unit->mWorld, unit->mDSP->getNumInputs()*BUFLENGTH*sizeof(float)); - if (mem) { - goto end; - } + ClearUnitIfMemFailed(mem); for (int i = 0; i < unit->mDSP->getNumInputs(); ++i) { // Initialize interpolator. unit->mInBufValue[i] = IN0(i); @@ -599,11 +593,6 @@ void Faust_Ctor(Faust* unit) // module constructor } } -end: - Print("Faust[%s]: RT memory allocation failed, try increasing the real-time memory size in the server options\n", g_unitName); - RTFree(unit->mWorld, unit->mDSP); - RTFree(unit->mWorld, unit->mInBufCopy); - RTFree(unit->mWorld, unit->mInBufValue); // Fix for https://github.com/grame-cncm/faust/issues/13 ClearUnitOutputs(unit, 1); } @@ -621,7 +610,9 @@ void Faust_Dtor(Faust* unit) // Module destructor } // delete dsp - unit->mDSP->~FAUSTCLASS(); + if (unit->mDSP != nullptr) { + unit->mDSP->~FAUSTCLASS(); + } RTFree(unit->mWorld, unit->mDSP); RTFree(unit->mWorld, unit->mControlInputs);