uCalc API Version: 2.1.3-preview.2 Released: 6/16/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:
Frees the memory and resources associated with a compiled expression object, making it invalid for future use.
Syntax
Parameters
Return
void
This method does not return a value.
Remarks
When you parse an expression with Parse, uCalc compiles the string into an efficient, executable object (an Abstract Syntax Tree or AST). This process allocates memory that is managed by the uCalc engine. The Release method is the explicit command to deallocate this memory and destroy the expression object.
Once an expression is released, its handle becomes invalid, and any attempt to use it will result in undefined behavior.
🗑️ Why Release?
uCalc's core is written in C++, and it manages its own memory for performance. Parsed expressions are not automatically garbage-collected by managed runtimes like .NET. Therefore, failing to release an expression object that you no longer need will cause a memory leak. It is crucial to have a clear strategy for releasing expressions, especially those created inside loops or in long-running applications.
🔧 Release Mechanisms
There are three primary ways an expression is released:
1. Manual Release
This is the most direct approach. You explicitly call the Release() method on the expression object.
var expr = uc.Parse("1 + 2");// ... use the expression ...expr.Release(); // Manually free the memory.2. Automatic (Scoped) Release - Best Practice
The recommended approach is to use language features that guarantee resource cleanup. This pattern, known as RAII (Resource Acquisition Is Initialization) in C++, ensures that Release() is called automatically when the object goes out of scope.
- C# / VB.NET: Use a
usingblock. Thenewstatement in the examples below translates to this. - C++: Call Owned.
This is the safest way to prevent memory leaks.
// The expression is automatically released at the end of the scope.using (var expr = new uCalc.Expression("5 * 10")) {Console.WriteLine(expr.Evaluate());}3. Implicit Release
When you release a parent uCalc instance, all objects it owns—including all parsed expressions, variables, functions, etc.—are automatically released.
⚖️ Comparative Analysis
vs. Managed Garbage Collection (C#): Standard .NET objects are tracked by the garbage collector. uCalc's
Expressionobjects, however, are wrappers around native C++ resources.Release()is the bridge that allows your managed code to correctly signal to the unmanaged core that the memory can be freed. Theusingstatement (IDisposable) is the standard C# pattern for this.vs. Manual
new/delete(C++): WhileRelease()is conceptually similar todelete, uCalc's scoped constructors and theOwnedpattern provide a much safer, RAII-compliant model that helps prevent common C++ pitfalls like forgetting to calldelete.
Examples
A simple demonstration of parsing an expression and then manually releasing it.
using uCalcSoftware;
var uc = new uCalc();
var expr = uc.Parse("1 + 2");
Console.WriteLine(expr.EvaluateStr());
// Manually release the expression when it's no longer needed.
expr.Release();
3 using uCalcSoftware; var uc = new uCalc(); var expr = uc.Parse("1 + 2"); Console.WriteLine(expr.EvaluateStr()); // Manually release the expression when it's no longer needed. expr.Release();
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto expr = uc.Parse("1 + 2");
cout << expr.EvaluateStr() << endl;
// Manually release the expression when it's no longer needed.
expr.Release();
}
3 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto expr = uc.Parse("1 + 2"); cout << expr.EvaluateStr() << endl; // Manually release the expression when it's no longer needed. expr.Release(); }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim expr = uc.Parse("1 + 2")
Console.WriteLine(expr.EvaluateStr())
'// Manually release the expression when it's no longer needed.
expr.Release()
End Sub
End Module
3 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim expr = uc.Parse("1 + 2") Console.WriteLine(expr.EvaluateStr()) '// Manually release the expression when it's no longer needed. expr.Release() End Sub End Module
Demonstrates the recommended practice of using a scoped block for automatic resource management, preventing memory leaks.
using uCalcSoftware;
var uc = new uCalc();
// A 'NewUsing' block ensures the expression is automatically released at the end of the scope.
// This is the safest pattern to prevent memory leaks.
using (var expr = new uCalc.Expression("5 * 10")) {
Console.WriteLine($"Result within scope: {expr.Evaluate()}");
}
// The 'expr' object is now released and its handle is invalid.
Console.WriteLine("Expression has been automatically released.");
Result within scope: 50
Expression has been automatically released. using uCalcSoftware; var uc = new uCalc(); // A 'NewUsing' block ensures the expression is automatically released at the end of the scope. // This is the safest pattern to prevent memory leaks. using (var expr = new uCalc.Expression("5 * 10")) { Console.WriteLine($"Result within scope: {expr.Evaluate()}"); } // The 'expr' object is now released and its handle is invalid. Console.WriteLine("Expression has been automatically released.");
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
// A 'NewUsing' block ensures the expression is automatically released at the end of the scope.
// This is the safest pattern to prevent memory leaks.
{
uCalc::Expression expr("5 * 10");
expr.Owned(); // Causes expr to be released when it goes out of scope
cout << "Result within scope: " << expr.Evaluate() << endl;
}
// The 'expr' object is now released and its handle is invalid.
cout << "Expression has been automatically released." << endl;
}
Result within scope: 50
Expression has been automatically released. #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; // A 'NewUsing' block ensures the expression is automatically released at the end of the scope. // This is the safest pattern to prevent memory leaks. { uCalc::Expression expr("5 * 10"); expr.Owned(); // Causes expr to be released when it goes out of scope cout << "Result within scope: " << expr.Evaluate() << endl; } // The 'expr' object is now released and its handle is invalid. cout << "Expression has been automatically released." << endl; }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
'// A 'NewUsing' block ensures the expression is automatically released at the end of the scope.
'// This is the safest pattern to prevent memory leaks.
Using expr As New uCalc.Expression("5 * 10")
Console.WriteLine($"Result within scope: {expr.Evaluate()}")
End Using
'// The 'expr' object is now released and its handle is invalid.
Console.WriteLine("Expression has been automatically released.")
End Sub
End Module
Result within scope: 50
Expression has been automatically released. Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() '// A 'NewUsing' block ensures the expression is automatically released at the end of the scope. '// This is the safest pattern to prevent memory leaks. Using expr As New uCalc.Expression("5 * 10") Console.WriteLine($"Result within scope: {expr.Evaluate()}") End Using '// The 'expr' object is now released and its handle is invalid. Console.WriteLine("Expression has been automatically released.") End Sub End Module
Illustrates the core relationship between the uCalc engine, an Item (variable), and a compiled Expression.
using uCalcSoftware;
var uc = new uCalc();
var VariableX = uc.DefineVariable("x");
var Expression = "x^2 * 10"; // Replace this with your expression
Console.WriteLine("--- Efficient: Parse() once, then Evaluate() in a loop ---");
var ParsedExpr = uc.Parse(Expression);
for (double x = 1; x <= 10; x++) {
VariableX.Value(x);
Console.WriteLine(ParsedExpr.Evaluate());
}
ParsedExpr.Release();
VariableX.Release();
--- Efficient: Parse() once, then Evaluate() in a loop ---
10
40
90
160
250
360
490
640
810
1000 using uCalcSoftware; var uc = new uCalc(); var VariableX = uc.DefineVariable("x"); var Expression = "x^2 * 10"; // Replace this with your expression Console.WriteLine("--- Efficient: Parse() once, then Evaluate() in a loop ---"); var ParsedExpr = uc.Parse(Expression); for (double x = 1; x <= 10; x++) { VariableX.Value(x); Console.WriteLine(ParsedExpr.Evaluate()); } ParsedExpr.Release(); VariableX.Release();
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
auto VariableX = uc.DefineVariable("x");
auto Expression = "x^2 * 10"; // Replace this with your expression
cout << "--- Efficient: Parse() once, then Evaluate() in a loop ---" << endl;
auto ParsedExpr = uc.Parse(Expression);
for (double x = 1; x <= 10; x++) {
VariableX.Value(x);
cout << ParsedExpr.Evaluate() << endl;
}
ParsedExpr.Release();
VariableX.Release();
}
--- Efficient: Parse() once, then Evaluate() in a loop ---
10
40
90
160
250
360
490
640
810
1000 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; auto VariableX = uc.DefineVariable("x"); auto Expression = "x^2 * 10"; // Replace this with your expression cout << "--- Efficient: Parse() once, then Evaluate() in a loop ---" << endl; auto ParsedExpr = uc.Parse(Expression); for (double x = 1; x <= 10; x++) { VariableX.Value(x); cout << ParsedExpr.Evaluate() << endl; } ParsedExpr.Release(); VariableX.Release(); }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
Dim VariableX = uc.DefineVariable("x")
Dim Expression = "x^2 * 10" '// Replace this with your expression
Console.WriteLine("--- Efficient: Parse() once, then Evaluate() in a loop ---")
Dim ParsedExpr = uc.Parse(Expression)
For x As Double = 1 To 10
VariableX.Value(x)
Console.WriteLine(ParsedExpr.Evaluate())
Next
ParsedExpr.Release()
VariableX.Release()
End Sub
End Module
--- Efficient: Parse() once, then Evaluate() in a loop ---
10
40
90
160
250
360
490
640
810
1000 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() Dim VariableX = uc.DefineVariable("x") Dim Expression = "x^2 * 10" '// Replace this with your expression Console.WriteLine("--- Efficient: Parse() once, then Evaluate() in a loop ---") Dim ParsedExpr = uc.Parse(Expression) For x As Double = 1 To 10 VariableX.Value(x) Console.WriteLine(ParsedExpr.Evaluate()) Next ParsedExpr.Release() VariableX.Release() End Sub End Module
Expression constructor
using uCalcSoftware;
var uc = new uCalc();
uCalc.DefaultInstance.DefineVariable("x = 1.2");
uc.DefineVariable("x = 3.2");
var MyExprA = new uCalc.Expression();
var MyExprB = new uCalc.Expression("x+4.25");
var MyExprC = new uCalc.Expression("x+4.25", uCalc.DefaultInstance.DataTypeOf("int"));
var MyExprD = new uCalc.Expression(uc, "x+4.25");
MyExprA.Parse("x*100");
Console.WriteLine(MyExprA.Evaluate());
Console.WriteLine(MyExprB.Evaluate());
Console.WriteLine(MyExprC.Evaluate());
Console.WriteLine(MyExprD.Evaluate());
// Release expressions when no longer needed (see other example for auto-release)
MyExprA.Release();
MyExprB.Release();
MyExprC.Release();
MyExprD.Release();
120
5.45
5
7.45 using uCalcSoftware; var uc = new uCalc(); uCalc.DefaultInstance.DefineVariable("x = 1.2"); uc.DefineVariable("x = 3.2"); var MyExprA = new uCalc.Expression(); var MyExprB = new uCalc.Expression("x+4.25"); var MyExprC = new uCalc.Expression("x+4.25", uCalc.DefaultInstance.DataTypeOf("int")); var MyExprD = new uCalc.Expression(uc, "x+4.25"); MyExprA.Parse("x*100"); Console.WriteLine(MyExprA.Evaluate()); Console.WriteLine(MyExprB.Evaluate()); Console.WriteLine(MyExprC.Evaluate()); Console.WriteLine(MyExprD.Evaluate()); // Release expressions when no longer needed (see other example for auto-release) MyExprA.Release(); MyExprB.Release(); MyExprC.Release(); MyExprD.Release();
#include
#include "uCalc.h"
using namespace std;
using namespace uCalcSoftware;
int main() {
uCalc uc;
uCalc::DefaultInstance().DefineVariable("x = 1.2");
uc.DefineVariable("x = 3.2");
uCalc::Expression MyExprA;
uCalc::Expression MyExprB("x+4.25");
uCalc::Expression MyExprC("x+4.25", uCalc::DefaultInstance().DataTypeOf("int"));
uCalc::Expression MyExprD(uc, "x+4.25");
MyExprA.Parse("x*100");
cout << MyExprA.Evaluate() << endl;
cout << MyExprB.Evaluate() << endl;
cout << MyExprC.Evaluate() << endl;
cout << MyExprD.Evaluate() << endl;
// Release expressions when no longer needed (see other example for auto-release)
MyExprA.Release();
MyExprB.Release();
MyExprC.Release();
MyExprD.Release();
}
120
5.45
5
7.45 #include <iostream> #include "uCalc.h" using namespace std; using namespace uCalcSoftware; int main() { uCalc uc; uCalc::DefaultInstance().DefineVariable("x = 1.2"); uc.DefineVariable("x = 3.2"); uCalc::Expression MyExprA; uCalc::Expression MyExprB("x+4.25"); uCalc::Expression MyExprC("x+4.25", uCalc::DefaultInstance().DataTypeOf("int")); uCalc::Expression MyExprD(uc, "x+4.25"); MyExprA.Parse("x*100"); cout << MyExprA.Evaluate() << endl; cout << MyExprB.Evaluate() << endl; cout << MyExprC.Evaluate() << endl; cout << MyExprD.Evaluate() << endl; // Release expressions when no longer needed (see other example for auto-release) MyExprA.Release(); MyExprB.Release(); MyExprC.Release(); MyExprD.Release(); }
Imports System
Imports uCalcSoftware
Public Module Program
Public Sub Main()
Dim uc As New uCalc()
uCalc.DefaultInstance.DefineVariable("x = 1.2")
uc.DefineVariable("x = 3.2")
Dim MyExprA As New uCalc.Expression()
Dim MyExprB As New uCalc.Expression("x+4.25")
Dim MyExprC As New uCalc.Expression("x+4.25", uCalc.DefaultInstance.DataTypeOf("int"))
Dim MyExprD As New uCalc.Expression(uc, "x+4.25")
MyExprA.Parse("x*100")
Console.WriteLine(MyExprA.Evaluate())
Console.WriteLine(MyExprB.Evaluate())
Console.WriteLine(MyExprC.Evaluate())
Console.WriteLine(MyExprD.Evaluate())
'// Release expressions when no longer needed (see other example for auto-release)
MyExprA.Release()
MyExprB.Release()
MyExprC.Release()
MyExprD.Release()
End Sub
End Module
120
5.45
5
7.45 Imports System Imports uCalcSoftware Public Module Program Public Sub Main() Dim uc As New uCalc() uCalc.DefaultInstance.DefineVariable("x = 1.2") uc.DefineVariable("x = 3.2") Dim MyExprA As New uCalc.Expression() Dim MyExprB As New uCalc.Expression("x+4.25") Dim MyExprC As New uCalc.Expression("x+4.25", uCalc.DefaultInstance.DataTypeOf("int")) Dim MyExprD As New uCalc.Expression(uc, "x+4.25") MyExprA.Parse("x*100") Console.WriteLine(MyExprA.Evaluate()) Console.WriteLine(MyExprB.Evaluate()) Console.WriteLine(MyExprC.Evaluate()) Console.WriteLine(MyExprD.Evaluate()) '// Release expressions when no longer needed (see other example for auto-release) MyExprA.Release() MyExprB.Release() MyExprC.Release() MyExprD.Release() End Sub End Module