Hi Andrey,
Sorry for Top-Post. But I searched and still don’t know what is Top-Post, pardon me, and please explain a little.
Reply about :
After the destructor call, the object no longer exists, regardless of
whether the memory it used to be placed in is freed or not.
=====================================
This is true as a concept, but when we overload delete operator for global or for just one class,
we write “free(ptr)” inside that overloaded function (at least MS’ implementation of C++ works like this).
Which means, it’s practically separated-able: destructor called and free() called. And if we separate the two stages,
we can get something that we can not achieve before, just like get a clean reference decreasing method,
and free all effected objects all together.
==================================================================
Case 1:
struct A
{
unsigned int x = 0u;
~A() { x = 0xBAADF00D; }
};
rcgc_shared_ptr< A > p1;
{
rcgc_shared_ptr< A > p2(new A());
p1 = p2;
std::cout << p1->x << std::endl;
}
std::cout << p1->x << std::endl; // (1)
The above is a bug because (1) accesses the object A after its
destruction. If A::x was, say a unique_ptr, it would be null or pointing
to already freed memory.
======================
Why would we assign x with a useful value in destructors ?
Unlike the predicted behavior on my side,
this Case1 I run in main function, results in
0
baadf00d
(<
If you have Visual Studio and run the code which detects memory leak with #ifdef _WIN32 _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF); #endif
You will see no memory leak at all.
This check only shows that no memory is leaked. The problem here is not a memory leak but incorrect memory access (potential use-after-destory and use-after-free). ========================================== The thing is in reality, calling destructor is not same as freeing memory. Memory is still containing valid data if no one messes with it. And if the free(ptr) function is not called, no one can/should mess with it. The only thing would possible is calling the destructor for multiple times because the rcgc_shared_ptrs requests this action. But use-after-destroy can be still avoided. To avoid use-after-destroy, just keep the good manner like ~A(){ If(this->p!=nullptr) { delete this->p; this->p = nullptr; } } And everything will be safe. And also, no one should do important work inside of destructors besides freeing and avoid double freeing, don’t they? In one word, it is another way of seeing destruction of the object. BTW, is it correct that intuitive_ptr is another kind of COM IUnknown ? What would you do if a reference is pointed to the object itself?