Skip to main content

IY94697: operator delete called twice on exception

 

APAR status

  • Closed as program error.

Error description

  • Using a custom operator delete, the testcase (below) shows that
    it is called twice:
    once after a throw, and once again after the exception has been
    cauaght and handled.
    
    <test.cc>
    #include <stdio.h>
    #include <cstdlib>
    #include <new>
    
    void* operator new(size_t size) throw(std::bad_alloc)
    {
        void* p=(void*)malloc(size);
        printf("operator new(size_t %d): %#lx\n", size, p);
        return p;
    }
    
    void operator delete(void *p) throw()
    {
        printf("operator delete: %#lx\n", p);
        //free(p);
    }
    
    class A {
    public:
    
        A()  {
            printf("A::A():constructor   this=%#lx\n", this);
        };
    
        A(const A& a) {
            printf("A::A(const A&):copy constructor   this=%#lx
    copy=%#lx\n", this, a);
            *this = a;
        };
    
        virtual ~A() {
            printf("A::~A():destructor   this=%#lx\n", this);
        };
    
        A& operator=(const A& a) {
            printf("A::operator=:assignment operator   this=%#lx\n",
    this);
            return *this;
        };
    };
    
    class B {
    public:
    
        B() {
            obj = 0;
            printf("B::B():constructor   this=%#lx\n", this);
        };
    
        B(A *o) {
            obj = o;
            printf("B::B(B *):constructor   this=%#lx   obj=%#lx\n",
    this, o);
        };
    
        B(const B& b) {
            printf("B::B(const B&):copy constructor   this=%#lx
    copy=%#lx\n", this, b);
            *this = b;
        };
    
        B& operator=(const B& b) {
            obj = b.obj;
            printf("B::operator=:assignment operator   this=%#lx
    copy=%#lx\n", this, b);
            return *this;
        };
    
        virtual ~B() {
            printf("B::~B():destructor   this=%#lx   obj=%#lx\n",
    this, obj);
            if (obj) {
                delete obj;
            };
        };
    
        A* obj;
    };
    
    class C {
    public:
        C() {};
        virtual ~C() {};
    };
    
    inline A * hide_work() {
      return new A(A());
    }
    
    int main(int argc, char *argv[])
    {
        printf("Memory of object destroyed before end of life\n");
        B *b;
        try {
            printf("main:try before\n");
            b= new B(new A(A()));
    //        b= new B(hide_work()); // using this instead is safe
            printf("main:try after\n");
    //        C c; // strange workaround
            printf("main:before exception\n");
            throw 1;
        }
        catch (...) {
            printf("main:in exception\n");
        }
        printf("main:after catch\n");
        delete b;
        printf("main:end\n");
    }
    </test.cc>
    

Local fix

  • Create another local variable before the throw.
    or
    Use call a function to create the temporary variables instead of
    doing this inline to the creation of the new B object.
    (You could create locals to hold those values as well and things
    would work.)
    

Problem summary

  • TBD
    

Problem conclusion

  • TBD
    

Temporary fix

Comments

APAR Information

  • APAR number

    IY94697

  • Reported component name

    VA C++ PROF FOR

  • Reported component ID

    5765F5600

  • Reported release

    600

  • Status

    CLOSED PER

  • PE

    NoPE

  • HIPER

    NoHIPER

  • Special Attention

    NoSpecatt

  • Submitted date

    2007-02-09

  • Closed date

    2007-03-12

  • Last modified date

    2007-06-22

  • APAR is sysrouted FROM one or more of the following:

  • APAR is sysrouted TO one or more of the following:

    IY99559 IZ01350

Fix information

  • Fixed component name

    VA C++ PROF FOR

  • Fixed component ID

    5765F5600

Applicable component levels

  • R600 PSY U811611

       UP07/04/30 I 1000

Copyright and trademark information

IBM, the IBM logo and ibm.com are trademarks of International Business Machines Corp., registered in many jurisdictions worldwide. Other product and service names might be trademarks of IBM or other companies. A current list of IBM trademarks is available on the Web at "Copyright and trademark information" at www.ibm.com/legal/copytrade.shtml.

Rate this page

Please take a moment to complete this form to help us better serve you.

This material provides me with the information I need.






This material is clear and easy to understand.






Did the information help you to achieve your goal?

What updates, improvements, or related information would you like to see in this document?

Your response will be used to improve our document content. Requests for assistance, if applicable, should be submitted through your normal support channel as we cannot respond from this site.


Input the verification number to submit feedback:



Document information

Product categories:

Software

Software Development

Analysis, Modeling, Design & Construction

VisualAge C++

Compiler


Software version:

600


Reference #:

IY94697


IBM Group:

Software Group


Modified date:

2007-06-22

Translate my page