Search code examples
c++windowsmemory-managementkerneldevice-driver

Deleting dynamic memory pointed by static pointer


I have the following structure (simplified):

class myType
{
    static char* data;
    //more private data here
public:
    //public interface here
};

data is a resource shared between all the instances of myType and it points to a dynamically allocated memory (allocated by one of the instances upon initialization).

So far so good. The problem arises when I need to free the memory pointed by data. Reference counting isn't a solution here because it's a valid and possible situation to not have a single instance of myType at some point of execution - and later a new instance can be created - thus the data must persist.

I need to free that memory upon driver unload but unload isn't related to the actual destruction of myType objects, thus I'm forced to free the data manually. This would be acceptable but data is (and should be) private and inaccessible from the unload handler. Sure, I can create a static and public destroy function inside myType but that doesn't seem right - after all I didn't need the public initializer, so why would I need one to free the memory? That data shouldn't be accessible from outside myType instances.

I'll appreciate any insights on the subject.


Solution

  • Depending on the complexity of your code I would prefer one of two options:

    1. Have a static public destroyMetadata method, which needs to be called if any instances have been created during the execution. Personally I don't see anything particularry bad with having a method to destroy implicitely created data. The problem with this approach is just that it is a manual approach and therefore somewhat bugprone
    2. Create a (singleton) Unload-Handler, where you can register callbacks to be executed on cleanup. Then you can make your destroyMetadata a private static method and register it with the handler when data is first created. This is a bit more effort, but yields a cleaner design overall.

    Which of these two is right for you depends on how complex your cleanup is likely to become. If you have dozens of classes with custom cleanup the second option seems preferable since it yields better encapsulation and cleaner code overall. However if this the only part of your code, where you need such cleanup it is a bit overkill to write such a generalized handler (YAGNI), so the first approach, while conceptually messier, looks much better in that scenario.