-
Notifications
You must be signed in to change notification settings - Fork 207
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
BUG: memory of network->Adjlist not handle correctly (memory leak or double free) #789
Comments
My suggestion and the solution I applied in my local copy is to free the localadjlists in Alternatively, a more robust approach would consist of invalidating (and freeing) the adjencylists every time a new node or link is added to the network. This however, requires additional checks for the existence of the variable I will create a Pull request to solve this issue, where we can further discuss which approach to take (maybe both?). |
See the comment on the Issue.
Good catch and nice analysis. I agree with your fix. The only (small) downside I see is that when a user runs a water quality analysis after running hydraulics the adjacency lists have to be re-created once again (which won't happen if quality is run concurrently with hydraulics). |
Fix Issue #789 - free network Adjlist
There is an error in the memory management of the variable
network->Adjlist
: the list is allocated but not freed.This bug appeared in my code, where I use EPANET only for the hydraulic simulations of the network in an optimization problem. As the possible decision variables in the optimization problem (Anytown) include tank and pipe installation, I use the ability of the library to modify the network structure dynamically to respond to the changes made by the optimization algorithm.
The network nodes adjacency list is allocated during openH, but it is not freed in closeH. If we evaluate a new solution with a different number of nodes (e.g., we add a tank), the for loop in the function freeadjlists is using the wrong number of nodes, i.e., the new one (with the new tank) instead of the old one that was used to create the adjlist. The function
freeadjlists
and its counterpartsbuildadjlists
andlocaladjlists
use the variableNnodes
to manage the array of adjlists, which has size Nnodes+1. With the current version, these variables are only freed when closing a project (EN_close -> free data -> freeadjlists) or when a new hydraulic simulation is performed and the old one is deleted before starting a new simulation (EN_openH -> openhyd -> create sparse -> localadjlists -> freeadjlists).As freeadjlists iterates over the array of adjency lists using the current number of Nodes, if the number of nodes has changed since when the current adjlists have been created, it results in a memory leak (if the number of nodes is now less than before, then the last elements are never freed) of in a possible double free or some segmentation fault (if the number of nodes is now greater than before, then the for loop goes out of the boundaries of the netadjlists).
This may also happen if the water quality simulations are run, as I don't see the function
freeadjlists
being called anywhere. See the example below.The segmentation fault/double-free error is not easily replicable, as the compilers optimize the memory allocation and often when going out of boundary you end up with a zero value. However, the memory leak always happens if you keep removing nodes. I try to provide here an executable to show this error.
The same results are obtained by uncommenting the lines that call the quality solver.
The text was updated successfully, but these errors were encountered: