No.
It's not about the type void*
, it's about the allocator design.
new
and malloc
may work completely differently, or might not even share the same memory. So it's only logical that you're not allowed to send one into the other.
Also, even if you call free
, you will need to call ~Foo()
. Otherwise you still leaked objects.
GCC even has the decency to warn you:
<source>: In function 'int main()':
<source>:10:9: warning: 'void free(void*)' called on pointer returned from a mismatched allocation function [-Wmismatched-new-delete]
10 | free(pf);
| ~~~~^~~~
<source>:9:23: note: returned from 'void* operator new(long unsigned int)'
9 | Foo* pf = new Foo();// ok
| ^
Then you might try to run the program, but the address sanitizer will report an error and abort the program:
=================================================================
==1==ERROR: AddressSanitizer: alloc-dealloc-mismatch (operator new vs free) on 0x602000000010
#0 0x7fa4139b04f7 in free (/opt/compiler-explorer/gcc-11.2.0/lib64/libasan.so.6+0xb14f7)
#1 0x401177 in main /app/example.cpp:10
#2 0x7fa4133b60b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
#3 0x40109d in _start (/app/output.s+0x40109d)
0x602000000010 is located 0 bytes inside of 1-byte region [0x602000000010,0x602000000011)
allocated by thread T0 here:
#0 0x7fa4139b1f57 in operator new(unsigned long) (/opt/compiler-explorer/gcc-11.2.0/lib64/libasan.so.6+0xb2f57)
#1 0x401167 in main /app/example.cpp:9
#2 0x7fa4133b60b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
SUMMARY: AddressSanitizer: alloc-dealloc-mismatch (/opt/compiler-explorer/gcc-11.2.0/lib64/libasan.so.6+0xb14f7) in free
==1==HINT: if you don't care about these errors you may set ASAN_OPTIONS=alloc_dealloc_mismatch=0
==1==ABORTING
An object with a deleted destructor is not meant to be free, or instantiated in any conventional way.
You could however allocate a block of memory, placement new into it then destroy all subobjects (including base classes) when deallocating that memory block.