Delete invokes pointee dtor  implicitly b_u_t dtor never implicitly calls delete.
 See P64 ARM.
I feel delete is a 2-stepper — destruction and reclaim. Reclaiming the heap space of the pointee, not any real estate outside the pointee.
“Reclaim” is more accurate than “free”. Reclaim means this real estate could belong to new objects. Even reading it could trigger disasters.
Now, suppose your object has a pointer field. You should program your dtor to call delete. Default dtor never calls delete. Dtor bulldozes the real estate of the host object. A 4-byte pointer lives on that real estate, but the pointee object lives somewhere on heap.
^ delete reclaims pointee’s heap space, but the 4-byte pointer is not reclaimed. People can still use this pointer field/stackVar, that’s why we need to set it to null.
^ in contrast, dtor bulldozes the 4-byte pointer field but doesn’t touch the heap real estate of the pointee.
For a smart pointer, dtor and operator delete are somewhat decoupled. “Coupled carefully” is how i put it. Smart pointer must carefully decide when to call operator delete.
At a high level, delete is responsible for reclaiming HEAP memory of a pointee; destructor is responsible for bulldozing real estate (stack or heap) of host object.
Another sound byte —
default dtor never calls delete on a ptr *field*;
default dtor implicitly calls dtor of fields and parents; P277 ARM.
container dtor implicit calls dtor of elements. See P36 eff STL