views:

156

answers:

1

I'm having some trouble with a dynamically linked library calling my overloaded operator delete but not my operator new. My exe looks something like this:

class A {
public:
    void func() {
        t = dynLib::Type::CreateObject();
    }
    dynLib::Type t;
};

void main() {
    A a;
    a.func();
}

And then I have a statically linked library where I have my global overloaded operators and the dynamically linked library that's causing the problem. Basically what happens is, the dynLib::Type type contains an std::vector to which it adds an element in its constructor. So the type looks something like this

class Type {
public:
    Type() {
        v.push_back( T() );
    }

    std::vector< T > v;
};

When func() is called, a new instance of Type is created, passed by value and then assigned to t. The operator= in work there copies over the std::vector also through its operator=. This in turn calls deallocate on the old std::vector in t, since it already had an element added in its constructor. This deallocate call ends up calling my operator delete. The problem is, my operator new was never called so it's deleting a pointer in a completely different memory space (memory logging shows this).

Now, I'm probably just missing something. Since class A above holds a dynLib::Type object, it might get constructed before my operator new (from the static library) gets linked. Is that even possible? I'm not quite sure at which point the constructor of the composed dynLib::Type is called. The dynamic library uses the default stl allocators so it doesn't do anything funky.

I've tried recreating the same situation without the dynamically linked library, just by having the Type class in my exe. This doesn't cause the issue though so it leads me to believe it must have something to do with the link order.

+2  A: 

This is badness. You are in effect using STL objects across the DLL boundary. This is a big no-no and will continue causing headaches for you. The most likely source of linking problems is how the executable and the DLL use CRT. If one uses static (/MT) and the other is dynamic (/MD) you will see all sorts of weirdness, and overloaded operator new is usually the first one to glitch.

If the CRT is consistent across the board, then it should work, but it's still not recommended to use the DLL as though it's a static library.

Try to refactor the code so that you don't have to construct Type outside of the DLL, see if that makes it better.

Igor Zevaka
Both the library and my exe use the dynamic CRT. And what I'm mostly curious about is why does it use only my operator delete and not new? When I call func() above, the CreateObject() function is in the dll, shouldn't that make it use its own new/delete?
Flawe
But then it gets assigned to `t` which is in the executable, so it cals operator `new` that's in the executable. In theory it should just work, but for some reason it doesn't. This is a common problem: http://stackoverflow.com/questions/1085873/dll-memory-manager-mixup
Igor Zevaka