Pointer arithmetic calculates an element address by adding or subtracting an offset. In C++, arr[2] is shorthand for *(arr + 2): the offset advances by two elements, or 2*sizeof(element_type) bytes. This makes arrays convenient, but it also makes an array of derived objects unsafe to pass through a base-class array pointer. section 8.10
The mistake appears when code assumes substituting a derived pointer for a base pointer works equally for arrays. Indexing then advances by the size of a base object rather than the larger derived object. Elements can be read incorrectly, and deleting through the base array can call only base destructors, leaving the memory operation inconsistent with the actual array. section 8.10
A derived array passed as a base array
With B containing n and D adding m, printArray(ds) advances through D using B-sized steps. The observed output alternates between 0 and 1 instead of consistently reading the intended elements; deletion prints only destroying B. A type-preserving template version makes printArray and deleteArray operate on B* and D* separately, producing four D destructions paired with four B destructions.


