Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Special Interest Groups
  3. C++ Gurus
  4. Overriding new and delete operator
QtWS25 Last Chance

Overriding new and delete operator

Scheduled Pinned Locked Moved C++ Gurus
7 Posts 2 Posters 7.8k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • D Offline
    D Offline
    Debith
    wrote on 2 Mar 2011, 08:51 last edited by
    #1

    Hi!

    I'm working on QT and I'm currently writing test application to our code. We decided to try to detect also memory leaks with our objects, so we have overridden new and delete operators in following way.

    @
    // main.cpp

    void * operator new(unsigned int size) throw (std::bad_alloc)
    {
    void *ptr = (void *)malloc(size);
    Pointers::instance()->append(ptr);
    return(ptr);
    };

    void operator delete(void *p) throw()
    {
    Pointers::instance()->removeAll(p);
    free(p);
    };
    @

    class Pointers is singleton class, containing list of all allocated pointers. Because memory leaks are easy to detect from test cases, we keep only track about number of pointers.

    The Problem is:

    @
    // test.cpp

    void TestClass::testCanary() {
    QVERIFY(true);

    // Makes sure that environment works for new and delete -operators.
    QCOMPARE(NUM_POINTERS(), 0);
    int *i = new int(2);
    QCOMPARE(NUM_POINTERS(), 1);
    delete i;
    QCOMPARE(NUM_POINTERS(), 0);
    QWidget *w = new QWidget();
    QCOMPARE(NUM_POINTERS(), 1);
    delete w;
    QCOMPARE(NUM_POINTERS(), 0); // <------ FAILS!!!???
    

    }
    @

    The marked line fails and this happens only, when compiling code with Mingw32-make (GNU Make 3.81) coming with QT 4.7 packet. On Visual Studio 2008, the test passes.

    [edit] please use @ for code

    1 Reply Last reply
    0
    • F Offline
      F Offline
      Franzk
      wrote on 3 Mar 2011, 06:32 last edited by
      #2

      What does NUM_POINTERS() return?

      "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

      http://www.catb.org/~esr/faqs/smart-questions.html

      1 Reply Last reply
      0
      • D Offline
        D Offline
        Debith
        wrote on 3 Mar 2011, 07:43 last edited by
        #3

        #define NUM_POINTERS() Pointers::instance()->count()

        1 Reply Last reply
        0
        • D Offline
          D Offline
          Debith
          wrote on 3 Mar 2011, 07:49 last edited by
          #4

          Some more information...

          This does not work:
          @
          // test.cpp

          void TestClass::testCanary() {
          QVERIFY(true);

          // Makes sure that environment works for new and delete -operators.
          QCOMPARE(NUM_POINTERS(), 0);
          int *i = new int(2);
          QCOMPARE(NUM_POINTERS(), 1);
          delete i;
          QCOMPARE(NUM_POINTERS(), 0);
          QWidget *w = new QWidget();
          QCOMPARE(NUM_POINTERS(), 1);
          delete w;
          QCOMPARE(NUM_POINTERS(), 0); // <------ FAILS!!!???
          

          }
          @

          But this works:

          @
          // test.cpp

          void TestClass::testCanary() {
          QVERIFY(true);

          // Makes sure that environment works for new and delete -operators.
          QCOMPARE(NUM_POINTERS(), 0);
          int *i = new int(2);
          QCOMPARE(NUM_POINTERS(), 1);
          delete i;
          QCOMPARE(NUM_POINTERS(), 0);
          QWidget *w = new QWidget();
          QCOMPARE(NUM_POINTERS(), 1);
          ::delete w;                  // <------ notice ::
          QCOMPARE(NUM_POINTERS(), 0); // <------ SUCCEEDS!!!
          

          }
          @

          Anyone can explain? Of course, it is not solution to add '::' everywhere in the code.

          1 Reply Last reply
          0
          • F Offline
            F Offline
            Franzk
            wrote on 3 Mar 2011, 07:58 last edited by
            #5

            maybe QWidget or QObject has the delete operator overloaded? It seems like a bit of odd behavior at least.

            "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

            http://www.catb.org/~esr/faqs/smart-questions.html

            1 Reply Last reply
            0
            • F Offline
              F Offline
              Franzk
              wrote on 3 Mar 2011, 08:03 last edited by
              #6

              Hmmno.

              I used the following code:
              @
              #include <QApplication>
              #include <QWidget>
              #include <QDebug>

              int ptrs = 0;

              void * operator new(size_t size) throw (std::bad_alloc)
              {
              void *ptr = (void *)malloc(size);
              ptrs++;
              return(ptr);
              };

              void operator delete(void *p) throw()
              {
              ptrs--;
              free(p);
              };

              int main(int argc, char *argv[])
              {
              QApplication app(argc, argv);
              qDebug() << ptrs;
              QWidget *w = new QWidget;
              qDebug() << ptrs;
              delete w;
              qDebug() << ptrs;
              }
              @

              Which resulted in the following output:
              @1101
              1107
              1104@

              That probably means that you cannot assume that the amount you expect is almost always wrong...

              Anyway, in which objects do you expect memory leaks?

              "Horse sense is the thing a horse has which keeps it from betting on people." -- W.C. Fields

              http://www.catb.org/~esr/faqs/smart-questions.html

              1 Reply Last reply
              0
              • D Offline
                D Offline
                Debith
                wrote on 3 Mar 2011, 08:26 last edited by
                #7

                Full source here

                unittest_operatortest.pro
                @
                CONFIG += qtestlib console

                DEFINES += BUILD_QTILIB

                SOURCES += main.cpp
                SOURCES += unittest_operatortest.cpp

                HEADERS += unittest_operatortest.h
                @

                unittest_operatortest.h
                @
                #ifndef UNITTEST_OPERATORTEST
                #define UNITTEST_OPERATORTEST

                #include <QObject>
                #include <new>

                /*********************************************************************

                • DECLARATIONS
                  *********************************************************************/

                void * operator new(unsigned int size) throw (std::bad_alloc);
                void operator delete(void*) throw();
                void* operator new(size_t size, const std::nothrow_t&) throw ();
                void operator delete(void* ptr, const std::nothrow_t&) throw ();

                class Pointers : public QObject
                {
                public:
                static QList<void > instance();
                static void release();
                };

                #define MARK() Pointers::instance()->clear()
                #define NUM_POINTERS() Pointers::instance()->count()

                /*********************************************************************

                • TEST CLASS
                  *********************************************************************/

                class UnittestOperatorTest : public QObject
                {
                Q_OBJECT

                private slots:
                    void init();
                    void cleanup();
                
                // Test cases
                    void testCanary();
                

                };

                #endif // UNITTEST_OPERATORTEST
                @

                unittest_operatortest.cpp
                @
                #include "unittest_operatortest.h"

                #include <QApplication>
                #include <QtTest/QTest>
                #include <QDebug>

                /*********************************************************************

                • POINTER CLASS IMPLEMENTATION
                  *********************************************************************/

                static QList<void > globalAllocationList = NULL;

                QList<void > Pointers::instance()
                {
                if ( !globalAllocationList ) {
                globalAllocationList = static_cast<QList<void*>*>(malloc(sizeof(new QList<void >)));
                new (globalAllocationList) QList <void
                >;
                }
                return globalAllocationList;
                }

                void Pointers::release()
                {
                globalAllocationList->~QList();
                free(globalAllocationList);
                globalAllocationList = NULL;
                }

                /*********************************************************************

                • TEST CASES
                  *********************************************************************/

                void UnittestOperatorTest::init() {
                MARK();
                }

                void UnittestOperatorTest::cleanup() {
                }

                void UnittestOperatorTest::testCanary() {
                QVERIFY(true);

                // Makes sure that environment works for new and delete -operators.
                QCOMPARE(NUM_POINTERS(), 0);
                int *i = new int(2);
                QCOMPARE(NUM_POINTERS(), 1);
                delete i;
                QCOMPARE(NUM_POINTERS(), 0);
                QWidget *w = new QWidget();
                QCOMPARE(NUM_POINTERS(), 1);
                delete w;
                QCOMPARE(NUM_POINTERS(), 0);
                

                }
                @

                main.cpp
                @
                #include "unittest_operatortest.h"

                #include <QtTest/QTest>
                #include <QApplication>

                /*********************************************************************

                • OVERRIDE CODE
                  *********************************************************************/

                void * operator new(unsigned int size) throw (std::bad_alloc)
                {
                void *ptr = (void *)malloc(size);
                Pointers::instance()->append(ptr);
                return(ptr);
                };

                void operator delete(void *p) throw()
                {
                Pointers::instance()->removeAll(p);
                free(p);
                };

                void * operator new(unsigned int size, const std::nothrow_t&) throw ()
                {
                void *ptr = (void *)malloc(size);
                Pointers::instance()->append(ptr);
                return(ptr);
                };

                void operator delete(void *p, const std::nothrow_t&) throw()
                {
                Pointers::instance()->removeAll(p);
                free(p);
                };

                /*********************************************************************

                • MAIN FUNCTION
                  *********************************************************************/

                int main(int argc, char *argv[])
                {
                QApplication app(argc, argv);
                int ret = 0;

                UnittestOperatorTest testableClass;
                ret = QTest::qExec(&testableClass, argc, argv&#41;;
                
                return ret;
                

                }
                @

                1 Reply Last reply
                0

                1/7

                2 Mar 2011, 08:51

                • Login

                • Login or register to search.
                1 out of 7
                • First post
                  1/7
                  Last post
                0
                • Categories
                • Recent
                • Tags
                • Popular
                • Users
                • Groups
                • Search
                • Get Qt Extensions
                • Unsolved