Скорее всего, 4 байта содержат общее количество объектов в выделении, поэтому delete [] сможет перебрать все объекты в массиве, вызывая их деструктор.
Чтобы вернуть исходный адрес, вы можете сохранить таблицу поиска по адресу address / 16, в которой хранятся базовый адрес и длина. Это позволит вам найти оригинальное распределение. Однако вы должны убедиться, что ваше распределение + 4 не пересекает 16-байтовую границу.
EDIT:
Я пошел дальше и написал тестовую программу, которая создает 50 объектов с помощью деструктора new и вызывает delete []. Деструктор просто вызывает printf, поэтому он не будет оптимизирован.
#include <stdio.h>
class MySimpleClass
{
public:
~MySimpleClass() {printf("Hi\n");}
};
int main()
{
MySimpleClass* arr = new MySimpleClass[50];
delete [] arr;
return 0;
}
Ниже приведена частичная разборка, очищенная для большей разборчивости. Как видите, VC ++ хранит количество массивов в начальных 4 байтах.
; Allocation
mov ecx, 36h ; Size of allocation
call scratch!operator new
test rax,rax ; Don't write 4 bytes if NULL.
je scratch!main+0x25
mov dword ptr [rax],32h ; Store 50 in first 4 bytes
add rax,4 ; Increment pointer by 4
; Free
lea rdi,[rax-4] ; Grab previous 4 bytes of allocation
mov ebx,dword ptr [rdi] ; Store in loop counter
jmp StartLoop ; Jump to beginning of loop
Loop:
lea rcx,[scratch!`string' (00000000`ffe11170)] ; 1st param to printf
call qword ptr [scratch!_imp_printf; Destructor
StartLoop:
sub ebx,1 ; Decrement loop counter
jns Loop ; Loop while not negative
Этот бухгалтерский учет отличается от бухгалтерского учета, который выполняют malloc или HeapAlloc. Эти распределители не заботятся об объектах и массивах. Они видят только капли памяти с общим размером. VC ++ не может запрашивать у менеджера кучи общий размер выделения, потому что это будет означать, что менеджер кучи будет обязан выделять блок именно того размера, который вы запрашивали. Менеджер кучи не должен иметь этого ограничения - если вы запрашиваете 240 байтов для выделения 20 12-байтовых объектов, он может свободно возвращать 256-байтовый блок, который он сразу же получил.