Hi all, I'm pretty new to both "open arrays" and OOP, and am feeling a bit concerned about memory management and leaks in my code. I will jump straight into examples and questions:
type T_my_object = object (TObject) {...} end; T_my_class = class (TComponent) {...} end; type str_array_type = array of ansistring; int_array_type = array of integer; obj_array_type = array of T_my_object; cls_array_type = array of T_my_class; var str_arr : str_array_type; int_arr : int_array_type; obj_arr : obj_array_type; cls_arr : cls_array_type; begin {...} setlength(str_arr, some_maximum); setlength(int_arr, some_maximum); setlength(obj_arr, some_maximum); setlength(cls_arr, some_maximum); {...} First: what does setlength do about initialization? There are a couple different cases here... 1. If the setlength function is creating an array of things which happen to be stored as pointers (ansistrings in str_arr or class instances in cls_arr) then will the pointers be initialized to nil by setlength? Or do I need to manually initialize all pointers to nil, after calling setlength? (I guess for ansistrings that would require using fillchar ... but maybe setlength is already doing this?) 2. Of course the primary concern is cleaning up. For the ansistring case, can I simply call: setlength (str_arr, 0); ...and expect that the ansistring references will be properly decremented and cleaned up? Or do I need to explicitly clear them myself? for i := 0 to high(str_arr) do str_arr[i] := ''; setlength(str_arr, 0); 3. Similarly for the cls_arr, do I need to explicitly call the destructor? for i := 0 to high(cls_arr) do if cls_arr[i] <> nil then cls_arr[i].Destroy; setlength(cls_arr, 0); ...or will setlength call the destructor when the array is shrunk? (Assumably only for non-nil pointers :) As for the other types... for int_arr it must be a non-issue, and for obj_arr ... objects DO need to be destroyed! Although this is only a matter of curiousity, since I'm not using any objects that aren't classes And of course the "array in array" example comes to mind: var str_arr_arr : array of str_arr; begin setlength (str_arr_arr, 5); setlength (str_arr_arr[3], 17); {...} // is it necessary to free all of the members as seen below? for i := 0 to high(str_arr_arr) do setlength (str_arr_arr[i], 0); // or will setlength silently do the job anyway? setlength (str_arr_arr, 0); Conversely, do open arrays get automatically cleaned up as part of an object destruction, or do I need to write that into the destructor? type T_my_other_class = class (TComponent) private str_arr : str_array_type; int_arr : int_array_type; cls_arr : cls_array_type; public constructor Create (my_owner : TComponent; pass_size : integer); override; destructor Destroy; end; constructor T_my_other_class.Create (my_owner : TComponent; pass_size : integer); begin inherited Create (my_owner); setlength (str_arr, pass_size); setlength (int_arr, pass_size); end; destructor T_my_other_class.Destroy; begin for i := 0 to high(str_arr) do str_arr[i] := ''; // again :) setlength (str_arr, 0); setlength (int_arr, 0); // and what about cls_arr, even more messy of course :) inherited Destroy; end; 4. Is the above destructor actually doing anything that doesn't happen automatically? And the last case, objects embedded in objects: type T_my_third_class = class (TComponent) embedded_cls : T_my_other_class; bool_arr : bool_array_type; {...} end; 5. Do I need to override the destructor with one that explicitly calls embedded_cls.Destroy? Of course, I didn't ask until I was already knee-deep in several layers of this stuff... type third_class_array_type = array of T_my_third_class; T_group_array = class(TComponent) third_arr : third_class_array_type {...} end; var g_arr : array of T_group_array; ... and so on. Actually, I think that's as many layers as I've got! whew. Happily the program runs! I am doing a lot of this cleanup manually, though, and am now wondering if I should cut some of my cleanup code out as extraneous, or if I rather need to triple-check it and perhaps reinforce it with yet more cleanup code. Thanks! ~David. _______________________________________________ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/mailman/listinfo/fpc-pascal