Implement destructors for my classes. I admit I have absolutely no idea when I’m supposed to be doing this and when not. When I look at other plugins, it’s totally mysterious to me when and why destructors are implemented.
Free the expander message buffer as suggested in Module.hpp. In this case do I free the buffer in the mother module, the expander, or both?
If you intend to receive messages from an expander, allocate both message buffers with identical blocks of memory (arrays, structs, etc).
Remember to free the buffer in the Module destructor.
Thanks in advance for any help with this and for helping to reduce my C++ ignorance.
The rules for deletion aren’t that complicated. If you allocate it, you need to delete it. The only thing that makes it confusing is that Rack itself will delete any UI widgets you add, like buttons, sliders, I/O jacks.
If you suspect your expander buffers are the culprit, just remove the code the frees them. If they crash doesn’t go away, then it’s not that.
If you run address sanitizer on your plugin it will most likely tell you what’s up. It’s not too difficult to run on platforms besides windows.
This module does not implement its own destructor method, and I’m assuming that means that none of these member variables are deleted. Is this a problem?
Thank you very much for the reply and for the suggestions to resolve my problem, I appreciate it!
ah, good Q. short answer - probably not. There is a fancy name for this, and I don’t remember it. But the deal here is:
Module will be destroyed by VCV when your plugin is removed, and that wil cause SEQ3 to be destroyed.
member variables of simple types (like bool) never need to be destroyed, They didn’t cause a malloc/new when they were created.
Objects of a user defined type, like SchmittTrigger will also be destroyed automatically by the destructor of SEQ3. You should assume that if SchmittTrigger did any allocations, that it will free them itself in its own destructor.
That’s why a lot of people don’t like to put “naked” pointers in their classes - you need to remember to delete them, and you will forget sometimes. The cool kids would do it like this:
This way the shared pointer will “remember for you” to clean up. Actually, the cooler kids would use std::unique_ptr in this case, but I’m not that cool.
Bottom line - if you malloc something you better free it. It it’s just an object (non-pointer) in your class it will get destroyed as part of object destruction. The language guarantees it.
sorry - I could not get the three tick formatting to work, above. makes the fake code difficult to read. actually, the forum software also changed the code, above, at least on chrome. It should say
foo = std::make_shared<bar>()
But it seems to drop the word bar. [update] well, I put in triple ticks and single ticks. Looks ugly, but better than before.
I’m confused by the fact that you have a parent module declaring a pair of left messages AND an expander declaring a pair of right messages.
Normally only one of the modules would declare the pair of messages. And then the parent and expander swap that pair of messages.
I can’t see the rest of your code to know what you are doing, but it looks odd.
And other commenters are correct, you shouldn’t be using free at all on these, because you’ve not allocated them using malloc
edited to expand on this a bit
Arbitrary memory referred to using pointers can be allocated from the heap using malloc and then released again using free
Arbitrary classes referred to using pointers can be created using new and should be destroyed by using delete*
variables and classes referred to directly typically handled automatically. All the member variables that you have pointed out above will be released when the containing object is destroyed. That includes your examples from SEQ3 and your own float arrays.
*Typically widgets in VCVRack are created by you using new, but when you attach them to the scene tree using methods like addChild VCVRack takes on the responsibility for deleting them
Thanks for the reply! Yours and the other replies in this thread have helped very much to de-mystify this for me. Unfortunately I haven’t been able to reproduce my bug in HUNDREDS of attempts so… the struggle continues.