I want to create a function for creating and initializing a controlled type (a bit like a factory) in the following manner:
function Create return Controlled_Type
is
Foo : Controlled_Type;
begin
Put_Line ("Check 1")
return Foo;
end Create;
procedure Main
is
Bar : Controlled_Type := Create;
begin
Put_Line ("Check 2")
end Main;
output:
Initialize
Check 1
Adjust
Finalize
As the finalize will dispose of some objects that are pointed to in the controlled type I end up with dangling pointers in Bar, and somehow this immediately crashes the program, so I never see "Check 2".
This can easily be resolved by using new Controlled_Type and returning a pointer in the Create function. However, I like the idea of having the controlled type and not a pointer to it as finalization will automatically be called when Bar goes out of scope. If Bar was a pointer, I'd have to manually dispose of it.
Is there any way to do this properly without ending up with dangling pointers? Should I do some magic in the Adjust procedure?
Well, you should implement
Adjustappropriately!When you make a copy, it’s bitwise, so any pointer in the original is copied as-is to the copy. When the original is finalized and the pointed-to object is deallocated, you’re left with a pointer-to-hyperspace in the copy.
The thing to do is to allocate a new pointer, designating the same value as the original. Something like
If I comment out the line
This.P := new Integer'(Original_Value);inAdjust, I get (on macOS)