问题
Simplified version of my c++ Class:
class Class
{
public:
Class(uint32_t size_, uint8_t val_) buf(NULL), size(size_)
{
buf = new uint8_t[size];
memset(buf, val_, size);
}
~Class()
{
if(buf != NULL)
{
delete[] buf;
buf = NULL;
size = 0;
}
}
void FakeDtor()
{
if(buf != NULL)
{
delete[] buf;
buf = NULL;
size = 0;
}
}
protected:
uint8_t* buf;
uint32_t size;
}
Code of My unit test:
TEST_F(Classtest, testDestructor)
{
Class *buff = new Class(10,10);
ASSERT_NE(buff->getData(), (uint8_t*)NULL);
buff->~Class(); // buff->FakeDtor();
ASSERT_EQ(buff->getData(), (uint8_t*)NULL);
}
When I compile code using msbuild and run UT - explicit call to dtor works and UT passes. When I use g++ to compile and run UT using gtest - explicit call to dtor seems to fail because following assertion fails. When I Use FakeDtor() instead of ~Class() UT passes both on Windows and Linuix. What can cause dtor to not execute when calling it explicity under Linux?
回答1:
Reading the contents of the class after its non-trivial destructor ran invokes Undefined Behavior. It does not matter that the memory the object lived in is still there because you did not delete
it, the object itself is dead and can no longer be used.
Literally everything is allowed to happen if you do it anyways. The concept at hand is similar to a dangling pointer/reference, for example see this.
This being UB includes "that if a destructor sets data member values, since no valid program will ever be able to read those values, a compiler can optimise away the setting of those members." as pointed out by @hvd in a comment.
来源:https://stackoverflow.com/questions/38914383/explicit-destructor-call-is-not-working