In c++ calling delete
on an object allocated with new
calls the destructor of the class, and release the memory. Would there be any difference if, instead of deleting the object, one calls explicitly its destructor and then free the memory?
Consider, e.g., the following example.
#include <iostream>
struct A {
int i;
~A() { std::cout << "Destructor, i was " << i << std::endl; }
};
int main()
{
A* p = new A{3};
p->~A();
free(p);
return 0;
}
Compiling the code with g++
7.3.0 and clang
6.0.1, and with -Wextra -Wall -pedantic
does not raise any warning.
The output of the program, as expected is
Destructor, i was 3
Running the program with valgrind
/memcheck
gives an error of mismatched free/delete:
==27743== Memcheck, a memory error detector
==27743== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==27743== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==27743== Command: ./destructor
==27743==
Destructor, i was 3
==27743== Mismatched free() / delete / delete []
==27743== at 0x4C3033B: free (vg_replace_malloc.c:530)
==27743== by 0x4009FC: main (in /tmp/destructor)
==27743== Address 0x5bbac80 is 0 bytes inside a block of size 4 alloc'd
==27743== at 0x4C2F77F: operator new(unsigned long) (vg_replace_malloc.c:334)
==27743== by 0x4009DA: main (in /tmp/destructor)
==27743==
==27743==
==27743== HEAP SUMMARY:
==27743== in use at exit: 0 bytes in 0 blocks
==27743== total heap usage: 3 allocs, 3 frees, 73,732 bytes allocated
==27743==
==27743== All heap blocks were freed -- no leaks are possible
==27743==
==27743== For counts of detected and suppressed errors, rerun with: -v
==27743== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
However, there is no memory leak.
I know of course that the standard way to dispose of the object p
in the code above is to call delete
.
My question is more a formal one:
- Is
delete
fully equivalent to a call to destructor and afree
? Does the standard specify this, or I am running into UB with the code above?