Memory leak or not ?
Why OSVVM™? › Forums › VHDL › Memory leak or not ?
- This topic has 2 replies, 2 voices, and was last updated 2 years ago by Dirk.
-
AuthorPosts
-
November 22, 2022 at 11:18 #2095DirkMember
I have a question about implementation of access type objects in VHDL.
Suppose I have a not fully constrained type, for example:type t_my_type is array(natural range<>, natural range <>) of integer;
Now suppose I want to write a function that transforms an object of this type (possibly changing the array dimensions), for example:
function my_function(obj : t_my_type) return t_my_type is type t_my_type_p is access t_my_type; variable return_obj_p : t_my_type_p; -- I cannot declare an object of t_my_type directly because I don't know the fully -- constrained dimensions yet begin -- Determine fully constrained dimensions of return object ... -- Now create the return object return_obj_p := new t_my_type(...fully constrained dimensions...); -- Initialize contents of return_obj_p ... return return_obj_p.all; end function my_function;
The problem with this code is that after the return statement, there is no possibility anymore of manually deallocating the memory associated with return_obj_p.
So the question now is:WILL/SHOULD THE SIMULATOR TAKE CARE OF THIS DEALLOCATION? and IF YES, IS THAT GUARANTEED?
November 22, 2022 at 13:36 #2096Jim LewisMemberMemory leak. I do not think the simulators are able to handle this for you.
I should note general VHDL questions like this may get a response faster on StackOverflow, however, I have indeed encountered this one and know a couple of solutions.
The simplest that I have seen, but not used (so it may have flaws) is:
function my_function(obj : t_my_type) return t_my_type is type t_my_type_p is access t_my_type; variable return_obj_p : t_my_type_p; -- Function is impure so we can access return_obj_p -- and since we cannot pass access types to functions without VHDL-2019 impure function GetMyTypeValue return t_my_type is variable result : t_my_type(return_obj_p'range) ; -- get the constraints (**corrected**) begin result := return_obj_p.all ; deallocate(return_obj_p) ; return result ; end function GetMyTypeValue ; begin -- Determine fully constrained dimensions of return object ... -- Now create the return object return_obj_p := new t_my_type(...fully constrained dimensions...); -- Initialize contents of return_obj_p ... return GetMyTypeValue; end function my_function;
VHDL-2019 allows impure functions to have variable inout parameters and allows passing of the variable return_op_p on the interface, so a function like this could become more general.
VHDL-2019 also introduced sequential block statements to allow local declarative regions, so with that you can do the following.
function my_function(obj : t_my_type) return t_my_type is type t_my_type_p is access t_my_type; variable return_obj_p : t_my_type_p; begin -- Determine fully constrained dimensions of return object ... -- Now create the return object return_obj_p := new t_my_type(...fully constrained dimensions...); -- Initialize contents of return_obj_p ... block -- VHDL-2019 variable result : return_obj_p'subtype ; -- get the constraints begin result := return_obj_p.all ; deallocate(return_obj_p) ; return result; end block ; end function my_function;
Aldec has implemented much of VHDL-2019. For other vendors, be sure to ask them to implement VHDL-2019 in general and specifically this feature. This is not hard stuff, they are just being difficult.
I have used protected types to solve this, the solution is more general than this, but it is also considerably harder to implement.
Cheers,
JimNovember 27, 2022 at 08:11 #2105DirkMemberHi Jim,
Thank you for your elaborate (and much appreciated) reply.
It is very useful and confirms what I feared being the case: that this is in fact a memory leak…
The first solution you suggest was actually already on my mind as a working alternative (without the memory leak). But this approach has the side-effect that an additional ‘copy object’ is created before returning from the function, which is unfortunate and inefficient if we are talking about LARGE objects…
So I was – naively – assuming/hoping that the compiler would be ‘smart’ enough to know that in the specific case that a function is returning the contents of a – locally declared – pointer object (and not the pointer object itself), it should become responsible for managing that allocated memory, as there is no way for the caller of this function to be able to do this…Kind regards,
Dirk -
AuthorPosts
- You must be logged in to reply to this topic.