uCalc API Version: 2.1.3-preview.2 Released: 6/17/2026
Warning
uCalc API Preview Release Notice:The documentation describes the intended behavior of the API. The current preview build contains incomplete features, unoptimized performance, and is subject to breaking changes.
Release
Method
Product:
Class:
Explicitly releases a uCalc instance and frees all of its associated memory and resources.
Syntax
Parameters
Return
void
This method does not return a value.
Remarks
Core Concept: Freeing Engine Resources
The Release() method explicitly destroys a uCalc instance and deallocates all of its associated resources, including variables, functions, operators, transformers, and parsed expressions. It is the primary mechanism for manual memory management within the uCalc ecosystem.
Why Explicit Release is Necessary (Comparative Analysis)
uCalc's memory model is different from standard garbage-collected or native memory management, making Release() essential.
vs. C# Garbage Collection (GC): In C#, when a
uCalcobject variable goes out of scope, the C# Garbage Collector only reclaims the memory for the handle (the C# wrapper object). The underlying C++ engine instance, which holds the bulk of the data, remains in memory.Release()is the signal to destroy that underlying engine instance. Without it, you will have a memory leak.vs. C++
delete: uCalc uses its own internal memory manager for performance and object recycling. AuCalchandle is not a raw C++ pointer that can be managed withdelete. CallingRelease()ensures the object is returned to uCalc's internal pool correctly.
Interaction with Automatic Release Mechanisms
While Release() provides manual control, the recommended approach is to use language-specific scoping mechanisms that call Release() for you automatically:
- C# / VB.NET: Create the
uCalcinstance within ausingblock. The instance will be automatically released when the block is exited.
using (var myCalc = new uCalc()) {// ... use myCalc ...}// myCalc is automatically released here.- C++: For stack-allocated objects or by calling Owned(), the
uCalcinstance is released when its destructor is called at the end of its scope.
Use Release() explicitly when the lifetime of the uCalc object is not tied to a specific lexical scope.
Best Practices
- Avoid Releasing the Default: While possible, you should avoid calling
Release()on the instance returned by uCalc.GetDefaultInstance(). The engine expects a default instance to always be available. - Memory Recycling: Released instances are not completely destroyed but are returned to an internal pool. This means creating a new
uCalcinstance immediately after releasing one is a very fast operation, as the engine can recycle the previously used memory footprint.
Examples
Doing an Eval in the same uCalc instance a variable belongs to
using uCalcSoftware;
var uc = new uCalc();
var uc1 = new uCalc();
var uc2 = new uCalc();
var x1 = uc1.DefineVariable("x = 5");
var x2 = uc2.DefineVariable("x = 6");
Console.WriteLine(x1.uCalc.Eval("x*10")); // Same as uc1.Eval("x*10")
Console.WriteLine(x2.uCalc.Eval("x*10")); // Same as uc2.Eval("x*10")
uc1.Release(); // Since x1 is part of uc1, x1 is automatically released as well
uc2.Release(); // Since x2 is part of uc2, x2 is automatically released as well
// You should no longer use x1 or x2 because they were part of uc1 & uc2
// Don not try x1.uCalc().Eval("x*10"); or x2.uCalc().Eval("x*10");
50
60 using uCalcSoftware; var uc = new uCalc(); var uc1 = new uCalc(); var uc2 = new uCalc(); var x1 = uc1.DefineVariable("x = 5"); var x2 = uc2.DefineVariable("x = 6"); Console.WriteLine(x1.uCalc.Eval("x*10")); // Same as uc1.Eval("x*10") Console.WriteLine(x2.uCalc.Eval("x*10")); // Same as uc2.Eval("x*10") uc1.Release(); // Since x1 is part of uc1, x1 is automatically released as well uc2.Release(); // Since x2 is part of uc2, x2 is automatically released as well // You should no longer use x1 or x2 because they were part of uc1 & uc2 // Don not try x1.uCalc().Eval("x*10"); or x2.uCalc().Eval("x*10");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uCalc uc1;
uCalc uc2;
auto x1 = uc1.DefineVariable("x = 5");
auto x2 = uc2.DefineVariable("x = 6");
cout << x1.uCalc().Eval("x*10") << endl; // Same as uc1.Eval("x*10")
cout << x2.uCalc().Eval("x*10") << endl; // Same as uc2.Eval("x*10")
uc1.Release(); // Since x1 is part of uc1, x1 is automatically released as well
uc2.Release(); // Since x2 is part of uc2, x2 is automatically released as well
// You should no longer use x1 or x2 because they were part of uc1 & uc2
// Don not try x1.uCalc().Eval("x*10"); or x2.uCalc().Eval("x*10");
}
50
60 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uCalc uc1; uCalc uc2; auto x1 = uc1.DefineVariable("x = 5"); auto x2 = uc2.DefineVariable("x = 6"); cout << x1.uCalc().Eval("x*10") << endl; // Same as uc1.Eval("x*10") cout << x2.uCalc().Eval("x*10") << endl; // Same as uc2.Eval("x*10") uc1.Release(); // Since x1 is part of uc1, x1 is automatically released as well uc2.Release(); // Since x2 is part of uc2, x2 is automatically released as well // You should no longer use x1 or x2 because they were part of uc1 & uc2 // Don not try x1.uCalc().Eval("x*10"); or x2.uCalc().Eval("x*10"); }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim uc1 As New uCalc()
Dim uc2 As New uCalc()
Dim x1 = uc1.DefineVariable("x = 5")
Dim x2 = uc2.DefineVariable("x = 6")
Console.WriteLine(x1.uCalc.Eval("x*10")) '// Same as uc1.Eval("x*10")
Console.WriteLine(x2.uCalc.Eval("x*10")) '// Same as uc2.Eval("x*10")
uc1.Release() '// Since x1 is part of uc1, x1 is automatically released as well
uc2.Release() '// Since x2 is part of uc2, x2 is automatically released as well
'// You should no longer use x1 or x2 because they were part of uc1 & uc2
'// Don not try x1.uCalc().Eval("x*10"); or x2.uCalc().Eval("x*10");
End Sub
End Module
50
60 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim uc1 As New uCalc() Dim uc2 As New uCalc() Dim x1 = uc1.DefineVariable("x = 5") Dim x2 = uc2.DefineVariable("x = 6") Console.WriteLine(x1.uCalc.Eval("x*10")) '// Same as uc1.Eval("x*10") Console.WriteLine(x2.uCalc.Eval("x*10")) '// Same as uc2.Eval("x*10") uc1.Release() '// Since x1 is part of uc1, x1 is automatically released as well uc2.Release() '// Since x2 is part of uc2, x2 is automatically released as well '// You should no longer use x1 or x2 because they were part of uc1 & uc2 '// Don not try x1.uCalc().Eval("x*10"); or x2.uCalc().Eval("x*10"); End Sub End Module
Creating uCalc instances
using uCalcSoftware;
var uc = new uCalc();
uc.DefineVariable("x = 123");
var uc1 = new uCalc(); // Creates a new instance
Console.WriteLine(uc1.EvalStr("x")); // uc1 does not have a variable named x
uc1.Release(); // Releases uc1 if it is no longer needed
var uc2 = uc.Clone(); // Creates new instance that is a clone of uc
Console.WriteLine(uc2.EvalStr("x")); // starts with the value of x obtained from uc
uc2.Eval("x = 456"); // Changes the value of x in uc1 but not uc
Console.WriteLine(uc2.EvalStr("x"));
Console.WriteLine(uc.EvalStr("x")); // The original x in uc remains unchanged
uc2.Release();
// Language specific - auto-releasing uCalc object
{ // Instances pointed to by neither uCalc1 nor uCalc2 will be released when they go out of scope
var uCalc1 = new uCalc();
var uCalc2 = uc.Clone();
// Call uCalc1.Release() and uCalc2.Release() explicitly if want to release them
}
{ // The instances that both uCalc1 and uCalc2 point to will be released when uCalc1 and uCalc2 go out of scope
using var uCalc1 = new uCalc();
using var uCalc2 = uc.Clone();
// No need for uCalc1.Release() or uCalc2.Release(), they will automatically be released
}
Undefined identifier
123
456
123 using uCalcSoftware; var uc = new uCalc(); uc.DefineVariable("x = 123"); var uc1 = new uCalc(); // Creates a new instance Console.WriteLine(uc1.EvalStr("x")); // uc1 does not have a variable named x uc1.Release(); // Releases uc1 if it is no longer needed var uc2 = uc.Clone(); // Creates new instance that is a clone of uc Console.WriteLine(uc2.EvalStr("x")); // starts with the value of x obtained from uc uc2.Eval("x = 456"); // Changes the value of x in uc1 but not uc Console.WriteLine(uc2.EvalStr("x")); Console.WriteLine(uc.EvalStr("x")); // The original x in uc remains unchanged uc2.Release(); // Language specific - auto-releasing uCalc object { // Instances pointed to by neither uCalc1 nor uCalc2 will be released when they go out of scope var uCalc1 = new uCalc(); var uCalc2 = uc.Clone(); // Call uCalc1.Release() and uCalc2.Release() explicitly if want to release them } { // The instances that both uCalc1 and uCalc2 point to will be released when uCalc1 and uCalc2 go out of scope using var uCalc1 = new uCalc(); using var uCalc2 = uc.Clone(); // No need for uCalc1.Release() or uCalc2.Release(), they will automatically be released }
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uc.DefineVariable("x = 123");
uCalc uc1; // Creates a new instance
cout << uc1.EvalStr("x") << endl; // uc1 does not have a variable named x
uc1.Release(); // Releases uc1 if it is no longer needed
auto uc2 = uc.Clone(); // Creates new instance that is a clone of uc
cout << uc2.EvalStr("x") << endl; // starts with the value of x obtained from uc
uc2.Eval("x = 456"); // Changes the value of x in uc1 but not uc
cout << uc2.EvalStr("x") << endl;
cout << uc.EvalStr("x") << endl; // The original x in uc remains unchanged
uc2.Release();
// Language specific - auto-releasing uCalc object
{ // Instances pointed to by neither uCalc1 nor uCalc2 will be released when they go out of scope
auto uCalc1 = new uCalc();
auto uCalc2 = uc.Clone();
// Call uCalc1.Release() and uCalc2.Release() explicitly if want to release them
}
{ // The instances that both uCalc1 and uCalc2 point to will be released when uCalc1 and uCalc2 go out of scope
uCalc uCalc1;
uCalc uCalc2(uc.Clone());
// No need for uCalc1.Release() or uCalc2.Release(), they will automatically be released
}
}
Undefined identifier
123
456
123 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uc.DefineVariable("x = 123"); uCalc uc1; // Creates a new instance cout << uc1.EvalStr("x") << endl; // uc1 does not have a variable named x uc1.Release(); // Releases uc1 if it is no longer needed auto uc2 = uc.Clone(); // Creates new instance that is a clone of uc cout << uc2.EvalStr("x") << endl; // starts with the value of x obtained from uc uc2.Eval("x = 456"); // Changes the value of x in uc1 but not uc cout << uc2.EvalStr("x") << endl; cout << uc.EvalStr("x") << endl; // The original x in uc remains unchanged uc2.Release(); // Language specific - auto-releasing uCalc object { // Instances pointed to by neither uCalc1 nor uCalc2 will be released when they go out of scope auto uCalc1 = new uCalc(); auto uCalc2 = uc.Clone(); // Call uCalc1.Release() and uCalc2.Release() explicitly if want to release them } { // The instances that both uCalc1 and uCalc2 point to will be released when uCalc1 and uCalc2 go out of scope uCalc uCalc1; uCalc uCalc2(uc.Clone()); // No need for uCalc1.Release() or uCalc2.Release(), they will automatically be released } }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
uc.DefineVariable("x = 123")
Dim uc1 As New uCalc() '// Creates a new instance
Console.WriteLine(uc1.EvalStr("x")) '// uc1 does not have a variable named x
uc1.Release() '// Releases uc1 if it is no longer needed
Dim uc2 = uc.Clone() '// Creates new instance that is a clone of uc
Console.WriteLine(uc2.EvalStr("x")) '// starts with the value of x obtained from uc
uc2.Eval("x = 456") '// Changes the value of x in uc1 but not uc
Console.WriteLine(uc2.EvalStr("x"))
Console.WriteLine(uc.EvalStr("x")) '// The original x in uc remains unchanged
uc2.Release()
'// Language specific - auto-releasing uCalc object
#If False
{ '// Instances pointed to by neither uCalc1 nor uCalc2 will be released when they go out of scope
Dim uCalc1 = new uCalc()
Dim uCalc2 = uc.Clone()
'// Call uCalc1.Release() and uCalc2.Release() explicitly if want to release them
}
{ '// The instances that both uCalc1 and uCalc2 point to will be released when uCalc1 and uCalc2 go out of scope
'// No need for uCalc1.Release() or uCalc2.Release(), they will automatically be released
}
#End If
End Sub
End Module
Undefined identifier
123
456
123 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() uc.DefineVariable("x = 123") Dim uc1 As New uCalc() '// Creates a new instance Console.WriteLine(uc1.EvalStr("x")) '// uc1 does not have a variable named x uc1.Release() '// Releases uc1 if it is no longer needed Dim uc2 = uc.Clone() '// Creates new instance that is a clone of uc Console.WriteLine(uc2.EvalStr("x")) '// starts with the value of x obtained from uc uc2.Eval("x = 456") '// Changes the value of x in uc1 but not uc Console.WriteLine(uc2.EvalStr("x")) Console.WriteLine(uc.EvalStr("x")) '// The original x in uc remains unchanged uc2.Release() '// Language specific - auto-releasing uCalc object #If False { '// Instances pointed to by neither uCalc1 nor uCalc2 will be released when they go out of scope Dim uCalc1 = new uCalc() Dim uCalc2 = uc.Clone() '// Call uCalc1.Release() and uCalc2.Release() explicitly if want to release them } { '// The instances that both uCalc1 and uCalc2 point to will be released when uCalc1 and uCalc2 go out of scope '// No need for uCalc1.Release() or uCalc2.Release(), they will automatically be released } #End If End Sub End Module