Listing 2: Detecting delete

#include <algorithm>
#include <iostream>
#include <list>
#include <stdlib.h>

class X
    {
public:
    void *operator new(size_t n)
        {
        void *const p = malloc(n);
        allocations_.push_back(p);
        return p;
        }
    void operator delete(void *p)
        {
        allocations_.remove(p);
        free(p);
        }
    static void test(std::string const &label,
            X const *const p)
        {
        std::cout << label << std::endl;
        std::cout << "    ";
        list::iterator const location =
                std::find(allocations_.begin(),
                allocations_.end(), p);
        bool const allocated =
                (location != allocations_.end());
        if (!allocated)
            std::cout << "not ";
        std::cout << "allocated" << std::endl;
        std::cout << std::endl;
        }
private:
    typedef std::list<void *> list;
    static list allocations_;
    };

X::list X::allocations_;

#define TEST(statement) \
    statement; \
    X::test(#statement, p);

int main()
    {
    X *p;
    TEST(p = NULL)
    TEST(p = new X)
    TEST(delete p)
    TEST((p = new X, p->~X()))
    TEST(p->operator delete(p))
    }

/* expected run-time result:

p = NULL

  not allocated

p = new X

  allocated

delete p

  not allocated

(p = new X, p->~X())

  allocated

p->operator delete(p)

  not allocated

*/
— End of Listing —