Let's start with something from the c++ reference:
... delete[] is an operator with a very specific behavior: An expression with the delete[] operator, first calls the appropriate destructors for each element in the array (if these are of a class type) ...
I was wondering if I can tell delete[] to not call destructors, for example if I already know that the delete[] statement should be delete without []. That would be very useful for memory management/memory leak detection.
My intention is to not call the destructor. In a memory leak detector, I want to generate an error message instead of a segfault when delete[] is used on a pointer where memory was allocated using new without [].
A delete[] expression cannot become "delete without []". They are different expressions that do different things and cannot be mixed. Destructor calls are only a part of it.
If you want to manage memory, then do so through allocators, where allocation, construction, destruction, and deallocation are four separate actions, or in some equivalent manner.
(edit: didn't see the last update.. as a quick hack, you could replace the allocation functions. For a serious new vs delete[] analysis, look at how valgrind operates)
Thanks, I know that I must not mix delete and delete[]. The idea is to catch that error and display a warning instead of a segfault. An allocator is probably what I would need. In my case it's too much effort for a memory leak detector. I guess I'll have to live with the segfaults. Thanks again for helping.
Read your code and it doesn't seem to solve my issue. Overwriting the global operators new and delete[] doesn't help the destructors being called on statement delete[]. Defining them for a class shouldn't make a difference here. If I modify your class Foo
1 2 3 4 5 6 7 8
class Foo : public NewDeleteMismatchDetector
{
int* pi;
public:
Foo() { pi = newint; };
~Foo() {int i = *pi /*segfault here*/; delete pi; };
};
and
1 2 3 4 5 6 7 8 9 10 11
int main()
{
Foo* f = new Foo;
delete f; // ok
Foo* f2 = new Foo[10];
delete[] f2; // ok
Foo* f3 = new Foo();
delete[] f3; // slightly changed this
}
the operator delete[] for Foo* f3 is not called before the destructor for all elements, dereferencing the member pi.