digitalmars.D.learn - Memory leak issue between extern (c) and D function
- backtrack (53/53) Apr 13 2023 Dear All, I am new to D lang. I have been given a task to consume
- Paul Backus (13/37) Apr 13 2023 The GC does not clean up memory allocated by `malloc`. Since
- Guillaume Piolat (7/15) Apr 14 2023 That won't work because the C++ programm calling the D dynlib
- Guillaume Piolat (5/8) Apr 14 2023 Or simpler, add that object to a list of object in D DLL
- backtrack (9/26) Apr 14 2023 Thank you for your response.
- Guillaume Piolat (19/20) Apr 16 2023 With the D GC, your object can have three state:
- =?UTF-8?Q?Ali_=c3=87ehreli?= (12/17) Apr 15 2023 There must be a corresponding function to do the cleaning:
Dear All, I am new to D lang. I have been given a task to consume the .dll generated from a D lang project. I added extern (c) function for call the .dll from CPP file. i have code like below ``` // myfile.d extern(c) { mystruct* getmystruct() { mystruct* mystruct = cast(mystruct*)malloc(mystruct.sizeof); return mystruct; } char* do_some_work(const mystruct* mystruct , immutable(char)* input, int inputlenght) { InputStruct input; input.name = input[0..inputlenght]; auto output = mystruct.getValue(input); // do some process and return char* return output_char.ptr; } } struct mystruct { OutputStruct[] getValue(InputStruct input) { // some string operation and other operation done here return output } } struct InputStruct { string name; } struct OutputStruct { string name; string value; } ``` Now i have my cpp file which calls like below ``` mystruct* mystruct = lib.getmystruct(); char* output = lib.do_some_work(mystruct, "input", 5); ``` The problem i am facing is, the memory keep on increasing and i am not able to fix the memory issue. I am suspecting that since the D lang function is called from extern(c) function GC is not clearing the memeory. Can you please help me on this? Thank you
Apr 13 2023
On Friday, 14 April 2023 at 03:50:37 UTC, backtrack wrote:Dear All, I am new to D lang. I have been given a task to consume the .dll generated from a D lang project. I added extern (c) function for call the .dll from CPP file. i have code like below ``` // myfile.d extern(c) { mystruct* getmystruct() { mystruct* mystruct = cast(mystruct*)malloc(mystruct.sizeof); return mystruct; } ```[...]Now i have my cpp file which calls like below ``` mystruct* mystruct = lib.getmystruct(); char* output = lib.do_some_work(mystruct, "input", 5); ``` The problem i am facing is, the memory keep on increasing and i am not able to fix the memory issue. I am suspecting that since the D lang function is called from extern(c) function GC is not clearing the memeory.The GC does not clean up memory allocated by `malloc`. Since you're using `malloc` to allocate your memory, the only way you can free it is by using `free`. If you want the GC to clean up your memory, use `new` to allocate it instead of `malloc`. Like this: ```d mystruct* getmystruct() { return new mystruct; } ```
Apr 13 2023
On Friday, 14 April 2023 at 04:43:39 UTC, Paul Backus wrote:If you want the GC to clean up your memory, use `new` to allocate it instead of `malloc`. Like this: ```d mystruct* getmystruct() { return new mystruct; } ```That won't work because the C++ programm calling the D dynlib will not have its stack scanned, leading to that object being reclaimed early. OP could add another extern(C) D function to free the allocated object. Or another extern(C) D function to call GC.addRoot
Apr 14 2023
On Friday, 14 April 2023 at 11:15:59 UTC, Guillaume Piolat wrote:OP could add another extern(C) D function to free the allocated object. Or another extern(C) D function to call GC.addRootOr simpler, add that object to a list of object in D DLL __gshared list, then clear the list (or set individual reference to null) if you want to reclaim space.
Apr 14 2023
On Friday, 14 April 2023 at 11:15:59 UTC, Guillaume Piolat wrote:On Friday, 14 April 2023 at 04:43:39 UTC, Paul Backus wrote:Thank you for your response. I added something like this in extern (c) function. ``` __delete(output); ``` When i debugged, it shows null to output after executing above line. however the memory is not releasing. Thank you.If you want the GC to clean up your memory, use `new` to allocate it instead of `malloc`. Like this: ```d mystruct* getmystruct() { return new mystruct; } ```That won't work because the C++ programm calling the D dynlib will not have its stack scanned, leading to that object being reclaimed early. OP could add another extern(C) D function to free the allocated object. Or another extern(C) D function to call GC.addRoot
Apr 14 2023
On Friday, 14 April 2023 at 17:31:02 UTC, backtrack wrote:however the memory is not releasing.With the D GC, your object can have three state: - reachable by GC. If D code can see the reference, then it's "alive", kept alive by GC scanning. The GC finds the reference and doesn't touch it. This is the invariant that you need to maintain when interacting with C. - unreachable by GC and thus at a risk of being reclaimable at next GC collect. This happens when all your references are null. If you want immediate destructor, call .destroy() before nulling your references so that the object can't be scanned. By calling destroy() on all your objects manually, you can reach destruction determinism. - non-existing, memory has been reclaimed. You don't necessarily need to do that with __delete, this should be very rare even. If the references to the object are null, then their destructor will eventually be called if it wasn't already with .destroy, the memory eventually reclaimed. Usually you don't need to care about that state.
Apr 16 2023
On 4/13/23 20:50, backtrack wrote:mystruct* getmystruct() { mystruct* mystruct = cast(mystruct*)malloc(mystruct.sizeof); return mystruct; }There must be a corresponding function to do the cleaning: void freemystruct(mystruct* ptr) { free ptr; } You have to make sure on the D side that freemystruct() is called once for each getmystruct(). I have the following presentation that covers similar concepts: https://www.youtube.com/watch?v=FNL-CPX4EuM I think this point is most relevant: https://www.youtube.com/watch?v=FNL-CPX4EuM&t=1833s Ali
Apr 15 2023