Will there be the following memory issues?

Let's say that in the DLL implementation there is (for example, a cpp file):

class Base { protected: Something *some; public: virtual void init() { some = new Something(); } virtual ~Base() { delete some; } }; 

Then in my exe I do:

 class Derived : public Base { public: virtual void init() { some = new SomethingElse(); } }; int main() { Base *blah = new Derived; delete blah; } 

Could this cause problems if the DLL starts with a different version than exe?

if so, is there not boost, non C ++ 0x solution

thanks

+4
source share
5 answers

I think you need to write ~Derive() like this

 ~Derived() { delete some; some = 0; //this is must; so that `delete some` in ~Base() works perfectly; //note `delete (void*)0` is fine in C++! } 

Explanation:

Why would you write this even if ~Base() does the same (it looks like it does the same) because ~Derived() ensures that you remove your object from the same heap / memory -pool / etc they were created.

See these topics:

How to use a class in a DLL? Memory Management with char * Return Function


EDIT:

It would be better to add another virtual function, say deinit() , (the back of your virtual void init() ), override this also when overriding init() and do the division in deinit() .

 //DLL class Base { protected: Something *some; public: virtual void init() { some = new Something(); } virtual void deinit() { delete some; } virtual ~Base() { deinit(); } }; //EXE class Derived : public Base { public: virtual void init() { some = new SomethingElse(); } virtual void deinit() { delete some; //some=0 is not needed anymore! } }; 
+3
source

Derived highlighted by some , so he is responsible for his release. Overwrite the destructor ...

If you always follow this principle, your memory handling is much simpler.

0
source

There will be no problem, although obviously the code contained in Derived will never go to another executable.

The destructor for Base will correctly remove some if Something comes from SomethingElse and has a virtual destructor.

0
source

I think you should initialize something in your constructor.

Otherwise, the destructor will delete a random part of the memory.

 Base::Base() : Something(NULL) { } 
0
source

This ugly code is due to the protected variable.

I suggest changing it. First, let me make sure that all the logic of ownership is isolated, so that it is easier to prove the correctness.

 class Base { public: Base(): some(0) {} // better initialize it... virtual ~Base() { delete some; } void init() { delete some; some = this->initImpl(); } private: Base(Base const&); // no copy Base& operator=(Base const&); // no assignment virtual SomeType* initImpl() { return new SomeType(); } SomeType* some; }; // class Base class Derived: public Base { virtual SomeOtherType* initImpl() { return new SomeOtherType(); } }; 

This is only the first step, because you should not try to directly manipulate resources, you are only going to leak them. So now we take our brilliant interface and change the implementation:

 // something that you should definitely have for your base classes class noncopyable { protected: noncopyable() {} private: noncopyable(noncopyable const&); noncopyable& operator=(noncopyable const&); }; class Base: noncopyable { public: Base() {} virtual ~Base() {} void init() { some.reset(this->initImpl()); } private: virtual SomeType* initImpl() { return new SomeType(); } std::auto_ptr<SomeType> some; }; // class Base // same Derived class, that the beauty of insulation :) 

Isn't that a lot better?

0
source

Source: https://habr.com/ru/post/1334887/


All Articles