Let's assume I have the following code (https://godbolt.org/z/MW4ETf7a8):
X.h
#include <iostream>
struct X{
void* operator new(std::size_t size)
{
std::cout << "new X\n";
return malloc(size);
}
void operator delete(void* ptr)
{
std::cout << "delete X\n";
return free(ptr);
}
virtual ~X() = default;
};
struct ArenaAllocatedX : public X {
void* operator new(std::size_t size)
{
std::cout << "new ArenaAllocatedX\n";
return malloc(size);
}
void operator delete(void* ptr)
{
std::cout << "delete ArenaAllocatedX\n";
return free(ptr);
}
};
main.cpp
int main() {
X* x1 = new X();
delete x1;
X* x2 = new ArenaAllocatedX ();
delete x2;
}
Using GCC 10.3.1,
x1
calls the new
and delete
operators of class X
, while x2
calls of class ArenaAllocatedX
.
I understand how it will pick up the new
operator, as it has the actual class name to its right, but I don't understand how the delete
operator is picked for the subclass while being pointed to by X*
.
Are the new
/delete
operators considered functions inside the virtual table (I dumped the VTable using gcc -f-dump-lang-class
and yet I don't see any delete operators)?
The VTable dumps:
Vtable for X
X::_ZTV1X: 4 entries
0 (int (*)(...))0
8 (int (*)(...))(& _ZTI1X)
16 (int (*)(...))X::~X
24 (int (*)(...))X::~X
Class X
size=8 align=8
base size=8 base align=8
X (0x0x7f38cd807780) 0 nearly-empty
vptr=((& X::_ZTV1X) + 16)
Vtable for ArenaAllocatedX
ArenaAllocatedX::_ZTV15ArenaAllocatedX: 4 entries
0 (int (*)(...))0
8 (int (*)(...))(& _ZTI15ArenaAllocatedX)
16 (int (*)(...))ArenaAllocatedX::~ArenaAllocatedX
24 (int (*)(...))ArenaAllocatedX::~ArenaAllocatedX
Class ArenaAllocatedX
size=8 align=8
base size=8 base align=8
ArenaAllocatedX (0x0x7f38cd848680) 0 nearly-empty
vptr=((& ArenaAllocatedX::_ZTV15ArenaAllocatedX) + 16)
X (0x0x7f38cd807cc0) 0 nearly-empty
primary-for ArenaAllocatedX (0x0x7f38cd848680)
How does C++ pick which delete
operator to use in the code provided?
new
anddelete
operators are notvirtual
, so there is no need for them to be in the vtable. I don't think they would make much sensevirtual
, but I've never had cause to try it.g++
or similar. The details you describe about the vtable are specific to (versions of) that compiler, and any answers will also be specific to that compiler. There is no requirement in Standard C++ for there to even be a vtable, or that other implementations work the same way as g++ (and other implementations do implement things differently than g++).g++
tag because your question is specific to that compiler.