diff --git a/ReleaseNotes2_3.md b/ReleaseNotes2_3.md index cb8f151..2cf6f87 100644 --- a/ReleaseNotes2_3.md +++ b/ReleaseNotes2_3.md @@ -47,4 +47,5 @@ This document describes the changes and updates that have been made in version 2 - `EN_STATUS_REPORT` can now be used with `EN_getoption` and `EN_setoption` to get or set the type of status report that EPANET will generate (`EN_NO_REPORT`, `EN_NORMAL_REPORT` or `EN_FULL_REPORT`). - A possible parser error that could result in a Trace Node ID in an input file not being recognized was fixed. - Additional API functions for enabling/disabling controls and rules were added. + - Updated the internal function `getclosedlink` in report.c to use a loop instead of recursion to prevent a stack overflow during the analysis of very large disconnections. \ No newline at end of file diff --git a/src/report.c b/src/report.c index 14f55cf..31e0649 100644 --- a/src/report.c +++ b/src/report.c @@ -45,7 +45,7 @@ static void writeenergy(Project *); static int writeresults(Project *); static int disconnected(Project *); static void marknodes(Project *, int, int *, char *); -static void getclosedlink(Project *, int, char *); +static void getclosedlink(Project *, int, char *, int *); static void writelimits(Project *, int, int); static int checklimits(Report *, double *, int, int); static char *fillstr(char *, char, int); @@ -1287,7 +1287,7 @@ int disconnected(Project *pr) clocktime(rpt->Atime, time->Htime)); writeline(pr, pr->Msg); } - getclosedlink(pr, j, marked); + getclosedlink(pr, j, marked, nodelist); } // Free allocated memory @@ -1350,11 +1350,12 @@ void marknodes(Project *pr, int m, int *nodelist, char *marked) } } -void getclosedlink(Project *pr, int i, char *marked) +void getclosedlink(Project *pr, int i, char *marked, int *stack) /* **---------------------------------------------------------------- ** Input: i = junction index ** marked[] = marks nodes already examined +** stack[] = stack to hold nodes to examine ** Output: None. ** Purpose: Determines if a closed link connects to junction i. **---------------------------------------------------------------- @@ -1365,20 +1366,41 @@ void getclosedlink(Project *pr, int i, char *marked) int j, k; Padjlist alink; + int top = 0; + + // Mark the current junction as examined and push onto stack marked[i] = 2; - for (alink = net->Adjlist[i]; alink != NULL; alink = alink->next) - { - k = alink->link; - j = alink->node; - if (marked[j] == 2) continue; - if (marked[j] == 1) - { - sprintf(pr->Msg, WARN03c, net->Link[k].ID); - writeline(pr, pr->Msg); - return; + stack[top] = i; + + while (top >= 0) { + i = stack[top--]; + alink = net->Adjlist[i]; + + // Iterate through each link adjacent to the current node + while (alink != NULL) { + k = alink->link; + j = alink->node; + + // Skip nodes that have already been examined + if (marked[j] == 2) { + alink = alink->next; + continue; + } + + // If a closed link is found, return and display a warning message + if (marked[j] == 1) { + sprintf(pr->Msg, WARN03c, net->Link[k].ID); + writeline(pr, pr->Msg); + return; + } + + // Mark the node as examined and push it onto the stack + marked[j] = 2; + stack[++top] = j; + alink = alink->next; } - else getclosedlink(pr, j, marked); } + } void writelimits(Project *pr, int j1, int j2)