COCKOS
CONFEDERATED FORUMS
Cockos : REAPER : NINJAM : Forums
Forum Home : Register : FAQ : Members List : Search :
Old 03-08-2017, 08:59 AM   #1
Nowhk
Human being with feelings
 
Join Date: Mar 2016
Posts: 234
Default Do you "delete" within a DLL?

Hi all,

I'm curious to know if you delete your object when you instanciate it on the heap, within the VST (DLL) that IPlug will create.
For example, when I create and I attach a new control such as:

Code:
pGraphics->AttachControl(new IKnobMultiControl(this, kGainX, kGainY, kGain, &knob));
There is no point where I actually delete this memory. On all example I seen, there is no reference variable to this new memory allocation, which I can use in the future to free it.
I could do:

Code:
pGraphics->AttachControl(myControl = new IKnobMultiControl(this, kGainX, kGainY, kGain, &knob));
and than:

Code:
delete myControl;
on decostructor. But hey: I never see it, neither in the example projects.

Theoretically, that's a memory leak!
Fortunately, since I'm in a DLL, once I unload the VST from the DAW, all memory is free. Right?

So, can I avoid to delete/free the memory of my pointers within a plugin DLL? How do you manage them?
Often, when I try to use "delete" on decostructor and later I close the plugin, I get a access memory violation (it not always happens, but often).
Nowhk is offline   Reply With Quote
Old 03-08-2017, 09:14 AM   #2
schwa
Administrator
 
schwa's Avatar
 
Join Date: Mar 2007
Location: NY
Posts: 15,747
Default

[incorrect info deleted]

Last edited by schwa; 03-08-2017 at 01:07 PM.
schwa is offline   Reply With Quote
Old 03-08-2017, 10:54 AM   #3
Tale
Human being with feelings
 
Tale's Avatar
 
Join Date: Jul 2008
Location: The Netherlands
Posts: 3,645
Default

Quote:
Originally Posted by Nowhk View Post
Code:
pGraphics->AttachControl(myControl = new IKnobMultiControl(this, kGainX, kGainY, kGain, &knob));
and than:

Code:
delete myControl;
on decostructor. But hey: I never see it, neither in the example projects.
Actually I think that is because IGraphics automatically deletes all its "children".

Quote:
Originally Posted by schwa View Post
[incorrect info deleted]
The DLL is not necessarily unloaded when the plug-in object is destroyed, so I think it is still necessary to free memory used by the plug-in class, not?

Last edited by schwa; 03-08-2017 at 01:07 PM.
Tale is offline   Reply With Quote
Old 03-08-2017, 11:38 AM   #4
schwa
Administrator
 
schwa's Avatar
 
Join Date: Mar 2007
Location: NY
Posts: 15,747
Default

Quote:
Originally Posted by Tale View Post
The DLL is not necessarily unloaded when the plug-in object is destroyed, so I think it is still necessary to free memory used by the plug-in class, not?
Yes, that's true. I was answering generally about DLLs. But in a VST context, if you allocate memory on any host callback (like when your "main" function is called, or effOpen, or whenever) and don't ever explicitly free it, and the host doesn't unload the DLL, that memory will leak. REAPER won't unload the DLL unless the preference to "allow complete unload" is enabled. I don't know what other hosts do.
schwa is offline   Reply With Quote
Old 03-08-2017, 12:37 PM   #5
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by schwa View Post
[incorrect info deleted]
This does not seem to be correct at all, where are you getting this info from? I just tested this in a VST plugin of mine. I made it allocate a huge block of memory (with new double[100000000]) and never release it. In Reaper I have the option to fully unload a plugin turned on. (And confirmed it works by observing the Reaper process with Process Explorer.) If I set the plugin offline in Reaper, causing the DLL to unload, the memory leak I deliberately made is still there.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.

Last edited by schwa; 03-08-2017 at 01:08 PM.
Xenakios is offline   Reply With Quote
Old 03-08-2017, 01:07 PM   #6
schwa
Administrator
 
schwa's Avatar
 
Join Date: Mar 2007
Location: NY
Posts: 15,747
Default

Quote:
Originally Posted by Xenakios View Post
This does not seem to be correct at all
You are correct .. I was wrong. I'll edit my original post.
schwa is offline   Reply With Quote
Old 03-09-2017, 01:00 AM   #7
Nowhk
Human being with feelings
 
Join Date: Mar 2016
Posts: 234
Default

Quote:
Originally Posted by Tale View Post
Actually I think that is because IGraphics automatically deletes all its "children".
Oh nice, I see right now where this happens:

Code:
IGraphics::~IGraphics()
{
  if (mKeyCatcher)
    DELETE_NULL(mKeyCatcher);

  mControls.Empty(true);
  DELETE_NULL(mDrawBitmap);
  DELETE_NULL(mTmpBitmap);
}
Now this makes sense. Thanks.

The problem I have is that when I try to delete from heap the memory allocated for a custom IControl (i.e. class Oscillator : public IControl; which contains for example other custom IControl such as ICustomKnobs or ICustomButtons) from my base class:

Code:
MainIPlug::~MainIPlug() { 
	delete pOscillator1;
}
it raises an exception here, or with some other class also here, when I close the plug. It seems somethings is called before the decostructor of my base class, which introduce that error. I don't get the logic, so every time put a delete is a "guess" if it will be deleted automatically by the framework or not

Quote:
Originally Posted by Xenakios View Post
This does not seem to be correct at all, where are you getting this info from? I just tested this in a VST plugin of mine. I made it allocate a huge block of memory (with new double[100000000]) and never release it. In Reaper I have the option to fully unload a plugin turned on. (And confirmed it works by observing the Reaper process with Process Explorer.) If I set the plugin offline in Reaper, causing the DLL to unload, the memory leak I deliberately made is still there.
I guess there are two different memory things to cover here: the memory (stack) used when loading DLL (such as loading a standalone program in memory, which use a fixed process), which will be free automatically when I unload the DLL, and the memory (heap) allocated at runtime (which is not deallocated automatically when unload plugin/DLL; your huge double array for example), which deserve a proper/manual deletes. Am I right?
Nowhk is offline   Reply With Quote
Old 03-09-2017, 05:39 AM   #8
random_id
Human being with feelings
 
random_id's Avatar
 
Join Date: May 2012
Location: PA, USA
Posts: 356
Default

Quote:
Originally Posted by Nowhk View Post
it raises an exception here, or with some other class also here, when I close the plug. It seems somethings is called before the decostructor of my base class, which introduce that error. I don't get the logic, so every time put a delete is a "guess" if it will be deleted automatically by the framework or not
I think if it is a control that you are attaching to IGraphics, you don't have to worry about deleting the control. It is handled within the IGraphics deconstructor. If it is something unrelated (e.g., new array), you should be deleting it within the plugin's deconstructor.
__________________
Website: LVC-Audio
random_id is offline   Reply With Quote
Old 03-09-2017, 02:24 PM   #9
jack461
Human being with feelings
 
jack461's Avatar
 
Join Date: Nov 2013
Location: France
Posts: 181
Default

I had a (possibly) similar problem, because (to make a long story short) I have created controls that depend on other objects defined in my main plug-in class. When the plug-in quits, the destructor of the class deletes these objects, but the controls themselves remain referenced in IGraphics. When finally these controls are destructed in IGraphics.cpp, the destruction fails because the controls use objects that do not exist anymore.

It took me some time, but the best solution I found is to add this method in the class IGraphics, in IGraphics.h:
Code:
virtual void KillControls();
this code in IGraphics.cpp:
Code:
void IGraphics::KillControls()
{
    mControls.Empty(true);
}
and to call this in the appropriate place of my plug-in class destructor.
Code:
GetGUI()->KillControls();
So far, this seems to have worked correctly for months... And it doesn't break the other plug-ins.

Hope this helps.
jack461 is offline   Reply With Quote
Old 03-27-2017, 06:47 AM   #10
Nowhk
Human being with feelings
 
Join Date: Mar 2016
Posts: 234
Default

Quote:
Originally Posted by jack461 View Post
I had a (possibly) similar problem, because (to make a long story short) I have created controls that depend on other objects defined in my main plug-in class. When the plug-in quits, the destructor of the class deletes these objects, but the controls themselves remain referenced in IGraphics. When finally these controls are destructed in IGraphics.cpp, the destruction fails because the controls use objects that do not exist anymore.

It took me some time, but the best solution I found is to add this method in the class IGraphics, in IGraphics.h:
Code:
virtual void KillControls();
this code in IGraphics.cpp:
Code:
void IGraphics::KillControls()
{
    mControls.Empty(true);
}
and to call this in the appropriate place of my plug-in class destructor.
Code:
GetGUI()->KillControls();
So far, this seems to have worked correctly for months... And it doesn't break the other plug-ins.

Hope this helps.
Thanks for the reply! Sorry, I'm a bit busy these days
Well...

... why did you add this method? I see it already does this in IGraphic destructor:

Code:
mControls.Empty(true);
Does we need it?
Nowhk is offline   Reply With Quote
Old 10-19-2017, 08:09 AM   #11
1eqinfinity
Human being with feelings
 
Join Date: Apr 2014
Posts: 84
Default

As soon as you AttachControl() IGraphics owns it. More accurately, as long as the pointer to the control is in mControls member of IGraphics. So it will be deleted in the ~IGraphics().
Trying to delete already deleted object is undefined behaviour. You may be lucky and not catch runtime error, but I personally did catch a bunch of those during some experiments with IControls.
If you new(something) in your custom IControl class, you should delete(something).
However, it is always better to use smart pointers. Compared to audio thread graphics thread is not time critical at all, so there's no practical performance issue with that even when you have hundreds of controls.

Ideally, as I understand it, an audio plugin developer shouldn't worry about loading/unloading dlls. That is another layer of abstraction, that stuff should be handled by the framework and hosts. The developer writes code in correspondence with the framework logic and common sense
__________________
soundcloud.com/crimsonbrain

Last edited by 1eqinfinity; 10-19-2017 at 08:18 AM.
1eqinfinity is offline   Reply With Quote
Old 10-19-2017, 08:49 AM   #12
Xenakios
Human being with feelings
 
Xenakios's Avatar
 
Join Date: Feb 2007
Location: Oulu, Finland
Posts: 8,062
Default

Quote:
Originally Posted by 1eqinfinity View Post
If you new(something) in your custom IControl class, you should delete(something).
More accurately, if you "new something" and the returned pointer is not handed over to something like AttachControl that manages its lifetime, you should "delete something". But yeah, for those kinds of objects, best just to use them as values or via smart pointers.
__________________
I am no longer part of the REAPER community. Please don't contact me with any REAPER-related issues.
Xenakios is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 05:44 AM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.