Определенно нет эквивалента между delete int_ptr;
и delete char_ptr;
, основанным на сборке, скомпилированной из некоторого базового кода C ++:
//C++ Code
void delete_as_int(int* ptr) {
delete ptr;
}
void delete_as_char(char* ptr) {
delete ptr;
}
//Assembly; GCC 8.2 x86-64, no optimizations, c++17 mode
delete_as_int(int*):
push rbp
mov rbp, rsp
sub rsp, 16
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
mov esi, 4 //Difference!
mov rdi, rax
call operator delete(void*, unsigned long)
nop
leave
ret
delete_as_char(char*):
push rbp
mov rbp, rsp
sub rsp, 16
mov QWORD PTR [rbp-8], rdi
mov rax, QWORD PTR [rbp-8]
mov esi, 1 //Difference!
mov rdi, rax
call operator delete(void*, unsigned long)
nop
leave
ret
Проще говоря, сборка delete
и int*
вычисляет другое количество байтов для хранения в регистре, чем сборка для delete
a char*
.
Итак, на первый взгляд, ясно, что тип, который распознает компилятор, имеет значение.Даже если нет другой причины, кроме как гарантировать, что правильный объем памяти будет удален.Таким образом, вы не можете полагаться на то, что компилятор волшебным образом выведет правильное поведение для delete
указателя, тип которого был изменен вызовом reinterpret_cast
: вам нужно убедиться, что указатели delete
являются типом, которым они былисозданный как - или для полиморфных типов, убедитесь, что Deleter имеет значение virtual
.