Skip to content

Commit

Permalink
fix: prevent memory leaks in fixed delay initialization (#160)
Browse files Browse the repository at this point in the history
Fixes #159
  • Loading branch information
ToddFincannon authored Nov 19, 2021
1 parent bd42d54 commit e158b2f
Show file tree
Hide file tree
Showing 3 changed files with 14 additions and 12 deletions.
5 changes: 2 additions & 3 deletions src/EquationGen.js
Original file line number Diff line number Diff line change
Expand Up @@ -809,9 +809,8 @@ export default class EquationGen extends ModelReader {
exprs[i].accept(this)
// For DELAY FIXED, also initialize the support struct out of band, as it is not a Vensim var.
if (fn === '_DELAY_FIXED') {
this.emit(
`;\n ${this.var.fixedDelayVarName}${this.lhsSubscriptGen(this.var.subscripts)} = __new_fixed_delay(`
)
let fixedDelay = `${this.var.fixedDelayVarName}${this.lhsSubscriptGen(this.var.subscripts)}`
this.emit(`;\n ${fixedDelay} = __new_fixed_delay(${fixedDelay}, `)
this.setArgIndex(1)
exprs[1].accept(this)
this.emit(', ')
Expand Down
19 changes: 11 additions & 8 deletions src/c/vensim.c
Original file line number Diff line number Diff line change
Expand Up @@ -298,9 +298,9 @@ double* _VECTOR_SORT_ORDER(double* vector, size_t size, double direction) {
// ALLOCATE AVAILABLE
//
// Mathematical functions for calculating the normal pdf and cdf at a point x
double __pdf_normal(double x, double μ, double σ) {
double base = 1.0 / (σ * sqrt(2.0 * M_PI));
double exponent = -pow(x - μ, 2.0) / (2.0 * σ * σ);
double __pdf_normal(double x, double mu, double sigma) {
double base = 1.0 / (sigma * sqrt(2.0 * M_PI));
double exponent = -pow(x - mu, 2.0) / (2.0 * sigma * sigma);
return base * exp(exponent);
}
double __cdf_unit_normal_P(double x) {
Expand All @@ -320,7 +320,7 @@ double __cdf_unit_normal_Q(double x) {
// Calculate the unit cumulative distribution function from x to +∞, often known as Q(x).
return x >= 0.0 ? 1.0 - __cdf_unit_normal_P(x) : __cdf_unit_normal_P(-x);
}
double __cdf_normal_Q(double x, double σ) { return __cdf_unit_normal_Q(x / σ); }
double __cdf_normal_Q(double x, double sigma) { return __cdf_unit_normal_Q(x / sigma); }
// Access the doubly-subscripted priority profiles array by pointer.
enum { PTYPE, PPRIORITY, PWIDTH, PEXTRA };
double __get_pp(double* pp, size_t iProfile, size_t iElement) {
Expand Down Expand Up @@ -430,14 +430,17 @@ double* _ALLOCATE_AVAILABLE(
//
// DELAY FIXED
//
FixedDelay* __new_fixed_delay(double delay_time, double initial_value) {
FixedDelay* __new_fixed_delay(FixedDelay* fixed_delay, double delay_time, double initial_value) {
// Construct a FixedDelay struct with a ring buffer for the delay line.
// We don't know the size until runtime, so it must be dynamically allocated.
// The delay time is quantized to an integral number of time steps.
// The FixedDelay should be constructed at init time to latch the delay time and initial value.
FixedDelay* fixed_delay = malloc(sizeof(FixedDelay));
fixed_delay->n = (size_t)ceil(delay_time / _time_step);
fixed_delay->data = malloc(sizeof(double) * fixed_delay->n);
// Allocate memory on the first call only. Pass the same pointer back in on subsequent runs.
if (fixed_delay == NULL) {
fixed_delay = malloc(sizeof(FixedDelay));
fixed_delay->n = (size_t)ceil(delay_time / _time_step);
fixed_delay->data = malloc(sizeof(double) * fixed_delay->n);
}
fixed_delay->data_index = 0;
fixed_delay->initial_value = initial_value;
return fixed_delay;
Expand Down
2 changes: 1 addition & 1 deletion src/c/vensim.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ typedef struct {
} FixedDelay;

double _DELAY_FIXED(double input, FixedDelay* fixed_delay);
FixedDelay* __new_fixed_delay(double delay_time, double initial_value);
FixedDelay* __new_fixed_delay(FixedDelay* fixed_delay, double delay_time, double initial_value);

#ifdef __cplusplus
}
Expand Down

0 comments on commit e158b2f

Please sign in to comment.