4

I am working on a shared library and application on Centos platform [clang++, llvm3.9.0 and libc++] , and both library and application overload their own operator new and operator delete.

Everything is working fine except for 1 case. On calling copy constructor of std::string always calling operator new of application side:

Here is the senario:

std::string str1 ( "A very strange issue on CentOS using clang and libc++" ); //operator new of library side called.

std::string str2(str1); //operator new of application side called. WHY??

operator delete on both cases are called for library side.

Here are the logs when running the following code:

====================================================
operator new in shared library
operator new called Application side
operator delete in shared library
operator delete in shared library
====================================================

Shared Library side operator new and delete:

    void * operator new ( size_t len ) throw ( std::bad_alloc )
    {
        printf("operator new in shared library\n");
        void * mem = malloc( len );
        if ( (mem == 0) && (len != 0) ) throw std::bad_alloc();
        return mem;
    }

    void * operator new[] ( size_t len ) throw ( std::bad_alloc )
    {
        printf("operator new[] in shared library\n");
        void * mem = malloc( len );
        if ( (mem == 0) && (len != 0) ) throw std::bad_alloc();
        return mem;
    }

    void operator delete ( void * ptr ) throw()
    {
        printf("operator delete in shared library\n");
        if ( ptr != 0 ) free ( ptr );
    }

    void operator delete[] ( void * ptr ) throw()
    {
        printf("operator delete[] in shared library\n");
        if ( ptr != 0 ) free ( ptr );
    }

Application side operator new and operator delete:

void * operator new ( size_t len ) throw ( std::bad_alloc )
{
    void * mem = malloc ( len );
    printf("operator new called Application side\n");
    if ( (mem == 0) && (len != 0) ) throw std::bad_alloc();
        return mem;
}

void * operator new[] ( size_t len ) throw ( std::bad_alloc )
{
    void * mem = malloc ( len );
    printf("operator new[] called Application side\n");
    if ( (mem == 0) && (len != 0) ) throw std::bad_alloc();
        return mem;
}

void operator delete ( void * ptr ) throw()
{
    printf("operator delete[] called Application side\n");
    if ( ptr != 0 )free ( ptr );
}

void operator delete[] ( void * ptr ) throw()
{
    printf("operator delete[] called Application side\n");
    if ( ptr != 0 ) free ( ptr );
}

Please help.

1 Answer 1

8

Short answer: Don't do that.

There's only supposed to be one replacement operator new (ok, there are a bunch of flavors, like noexcept, and [], etc, but only one of each flavor).

If you have more than one, then - as you have discovered - it is not clear which one gets called, and you can get mismatched calls to new and delete, which is a quick trip to undefined behavior.

I could explain why you're getting the exact behavior that you're reporting, but it has to do with inlining, and extern templates, and it doesn't really matter. You have two replacement functions for operator new, and that's the problem.

Sign up to request clarification or add additional context in comments.

5 Comments

You have two replacement functions for operator new, and that's the problem. What does this mean? Are you talking about replacement new operator?
@aga it means exactly what it says. In C++ operator new is replacable, so the program can replace the default version defined by the C++ runtime, like your program does, but you can only replace it once. Are you confusing "replacement" with "placement"?
@JonathanWakely yes, I was confused. Thanks for clarification. This behaviour is visible only on centos with clang, not with gcc or on any other platform like windows. Also why it is calling application side operator new when copy constructor of string is called and for all other scenarios, dll side opperator new is called.
Because your program has undefined behaviour. Anything can happen (including appearing to work as expected). Marshall already said "I could explain why you're getting the exact behavior that you're reporting, but it has to do with inlining, and extern templates, and it doesn't really matter." Instead of trying to reason about why it happens, fix your program.
@Marshall Can you explain me why this behaviour is occurring. You told that it is related to inlining and extern templates.This behaviour is observed only when library built using -o2 or -o3 optimisation. Also if I stop inlining using -fno-inline flag, this issue is not reproducing. I want to know how inline function involves in causing such behaviour. Please do explain.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.