Why is this not a memory leak in C++?

匆匆过客 提交于 2019-12-01 21:06:07

Deleting an object via a polymorphic pointer when the base class doesn't have a virtual destructor is undefined behaviour.

Undefined behaviour may mean your code leaks memory, crashes or works perfectly.

In this case the runtime library presumably allocated a single block of memory for your object and is able to delete that block correctly even when it is pointed to by a pointer of a different type. This is probably true for most runtimes but there are no guarantees. E.g. when using malloc() and free() you don't need to supply the size of the malloc() to free(), the same is happening here.

If you had defined a destructor in Derived you would see that it is not being called.

There would be a memory leak if b was an object that had resources (memory, network...) because of undefined behavior.

Here, by chance, the derived destructor doesn't do anything and the memory for the object is freed properly (this time). But anything more than built-in/trivially destructible types could trigger a memory leak (I suggest you try a vector of size 10 for instance).

BTW, o is not used?

It doesn't leak memory because of how your C++ implementation behaves, but it is undefined behavior and you should fix it.

It's not a memory leak in this case because...

  1. std::make_unique allocates using new:

    template<class T, class... Args> unique_ptr<T> make_unique(Args&&... args); [...]
    Returns: unique_­ptr<T>(new T(std::forward<Args>(args)...)).
    [unique.ptr.create]

  2. std::unique_ptr deallocates using the std::default_delete which uses operator delete.

It doesn't matter from the perspective of memory leaks that the types are different, because delete will still be called with the pointer to the object allocated by new.

It would also be a memory leak if Derived did not have a trivial destructor. If it held a std::vector for example, that vector's destructor would be called by ~Derived. If it's not called, the storage for the vector would (detectably) leak.

See also: How does delete work?

However, all of this is undefined behavior per the C++ standard, so it might theoretically stop working any time. See [expr.delete/3].

In a single-object delete expression, if the static type of the object to be deleted is different from its dynamic type and the selected deallocation function (see below) is not a destroying operator delete, the static type shall be a base class of the dynamic type of the object to be deleted and the static type shall have a virtual destructor or the behavior is undefined.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!