из С++ FAQ:
http://www.cs.uu.nl/wais/html/na-dir/C++-faq/part14.html==============================================================================
[35.7] How do compilers use "over-allocation" to remember the number of
elements in an allocated array?
Recall that when you delete[] an array, the runtime system magically knows how
many destructors to run[16.13]. This FAQ describes a technique used by some
C++ compilers to do this (the other common technique is to use an associative
array[35.8]).
If the compiler uses the "over-allocation" technique, the code for
p = new Fred[n] looks something like the following. Note that WORDSIZE is an
imaginary machine-dependent constant that is at least sizeof(size_t), possibly
rounded up for any alignment constraints. On many machines, this constant will
have a value of 4 or 8. It is not a real C++ identifier that will be defined
for your compiler.
// Original code: Fred* p = new Fred[n];
char* tmp = (char*) operator new[] (WORDSIZE + n * sizeof(Fred));
Fred* p = (Fred*) (tmp + WORDSIZE);
*(size_t*)tmp = n;
size_t i;
try {
for (i = 0; i < n; ++i)
new(p + i) Fred(); // Placement new[11.10]
} catch (...) {
while (i-- != 0)
(p + i)->~Fred(); // Explicit call to the destructor[11.10]
operator delete[] ((char*)p - WORDSIZE);
throw;
}
Then the delete[] p statement becomes:
// Original code: delete[] p;
size_t n = * (size_t*) ((char*)p - WORDSIZE);
while (n-- != 0)
(p + n)->~Fred();
operator delete[] ((char*)p - WORDSIZE);
Note that the address passed to operator delete[] is not the same as p.
Compared to the associative array technique[35.8], this technique is faster,
but more sensitive to the problem of programmers saying delete p rather than
delete[] p. For example, if you make a programming error by saying delete p
where you should have said delete[] p, the address that is passed to
operator delete(void*) is not the address of any valid heap allocation. This
will probably corrupt the heap. Bang! You're dead!
==============================================================================
[35.8] How do compilers use an "associative array" to remember the number of
elements in an allocated array?
Recall that when you delete[] an array, the runtime system magically knows how
many destructors to run[16.13]. This FAQ describes a technique used by some
C++ compilers to do this (the other common technique is to
over-allocate[35.7]).
If the compiler uses the associative array technique, the code for
p = new Fred[n] looks something like this (where arrayLengthAssociation is the
imaginary name of a hidden, global associative array that maps from void* to
"size_t"):
// Original code: Fred* p = new Fred[n];
Fred* p = (Fred*) operator new[] (n * sizeof(Fred));
size_t i;
try {
for (i = 0; i < n; ++i)
new(p + i) Fred(); // Placement new[11.10]
} catch (...) {
while (i-- != 0)
(p + i)->~Fred(); // Explicit call to the destructor[11.10]
operator delete[] (p);
throw;
}
arrayLengthAssociation.insert(p, n);
Then the delete[] p statement becomes:
// Original code: delete[] p;
size_t n = arrayLengthAssociation.lookup(p);
while (n-- != 0)
(p + n)->~Fred();
operator delete[] (p);
Cfront uses this technique (it uses an AVL tree to implement the associative
array).
Compared to the over-allocation technique[35.7], the associative array
technique is slower, but less sensitive to the problem of programmers saying
delete p rather than delete[] p. For example, if you make a programming error
by saying delete p where you should have said delete[] p, only the first Fred
in the array gets destructed, but the heap may survive (unless you've replaced
operator delete[] with something that doesn't simply call operator delete, or
unless the destructors for the other Fred objects were necessary).
==============================================================================
Т.е. delete p вместо delete[] p есть ошибка. Если деструктор тривиален, и компилятор реализует new[] ассоциативным массивом, то никакой разницы (что и утверждалось) замечено не будет. В противном случае возможна порча памяти.
Ну с практической точки зрения портабельность меня абсолютно не волнует, на С++ от Интел и MSVC delete=delete[]. Код у меня не портируемый на другие ОС по определению - нет нужды.
А теоретически было бы интересно посмотреть как это проявляется на GNU g++ и на ВСВ.