7

Hi I'm using a library that has globally overridden new/delete. But I have a problem with this library, the problem is that it has to be manually initialized in the main function.

Now I'm trying to use another library that initializes a few functions before main is called, unfortunately this library uses new within these functions. So I get errors because the memory manager that uses the overridden new/delete keywords are not initialized yet.

I'd really like to use the default memory manager because I want to add unit testing to this library. It would not make much sense to use the memory used my the library I want to test also used by my Unit Testing library.

So my question is if it's possible to ignore global overridden new/delete when including the second library and just use the default new/delete?

I'm using visual studio 2010 on Windows 7 with the standard C++ compiler.

Cœur
  • 37,241
  • 25
  • 195
  • 267
NomenNescio
  • 2,899
  • 8
  • 44
  • 82
  • The answer will depend on the platform and/or compiler. – atzz Sep 21 '12 at 12:51
  • Do you develop both libraries or are they third party ? If you are in control of the memory management code, i would deviate from overriding new/delete and create a *memory management object* in the style of `std::tr1::shared_ptr`. – count0 Sep 21 '12 at 13:40
  • @count0 We develop the Memory Manager library. It's a custom memory manager with a highly optimized garbage collector. And I'm trying to use the boost test libraries for unit testing. – NomenNescio Sep 21 '12 at 13:42
  • Use a memory management object then, it's much cleaner design, imho. Check *Scott Meyers: Effective C++: Item 13*. – count0 Sep 21 '12 at 13:43
  • I didn't design it. I just started working here ;-), I'm not gonna question the wisdom of my Boss Programmer just yet. – NomenNescio Sep 21 '12 at 13:44
  • It seems like your memory manager library is badly designed. Since global objects could use new/delete in their constructors, the library won't work with otherwise correct C++ code. Therefore, count0's answer is probably correct: the memory manager library should either support a mixed mode where some objects use the original new/delete functions and the library does not get into their way, or it should be initialized very early by platform specific (!) means. Initializing in main() is too late. – h2stein Oct 21 '12 at 12:52
  • You could probably get your library out of your way by using placement new or a class specific new operator. This depends on how the library has been designed and how your code looks that you want to test. – h2stein Oct 21 '12 at 12:54

3 Answers3

1

I do not think this is possible without modifying the library itself. I guess it is about a static library (inside a dll, the overridden new/delete will be pointed by the functions inside the dll.)

You can remove an obj file from a static library by using the command (Visual command prompt):

  LIB /REMOVE:obj_to_remove /OUT:removed.lib input.lib

To find out what obj to remove, first run:

  DUMPBIN /ARCHIVEMEMBERS input.lib

You will see lines such as

    Archive member name at 14286: /0  compilation.dir\objfile1.obj

14286 'identifies' the obj file. To see where each symbol is, run:

 DUMPBIN /LINKERMEMBER:1 input.lib > members.txt

and look for the new/delete. members.txt will contains the mangled names of each symbols and an identifier of the obj in which this symbol is. For instance

    14286 ?_Rank@?$_Arithmetic_traits@C@std@@2HB

The 14286 is telling you the obj 'identifier' in which the symbol lies. If you have trouble finding new/delete, you can run:

 DUMPBIN /SYMBOLS input.lib > sym.txt

which will flush into sym.txt the mangled and unmangled names for each symbol.

At the end, remove the obj file with the LIB command above by replacing obj_to_remove by compilation.dir\objfile1.obj in our example, and link against removed.lib.

Now, if you are not lucky, other symbols you need may be in the same object file as the new/delete. In that case, you can "hack" the lib using something like this (say renaming new to dew and delete to nelete.)

Community
  • 1
  • 1
Raffi
  • 3,068
  • 31
  • 33
0

Can you place the memory manager's initialization out of main into a shared lib ?

If this is possible you could try forcing the initialization order of your libraries (by dependency) to load (and initialize) the memory manager before anything else is loaded. This is however a very brittle (or specific) solution since it'll be dependent on platform specific workarounds for forcing the order in which shared libs are initialized.

count0
  • 2,537
  • 2
  • 22
  • 30
  • The overridden keywords are written in the header file so I can't really place it in another library, and I'd really like to use the default memory manager because I want to add unit testing to this library. It would not make much sense to use the memory used my the library I want to test also used by my Unit Testing library. – NomenNescio Sep 21 '12 at 13:24
  • Oh, forcing the order of initialization with dependencies could work, I don't know... but I still want to use the default new/delete, so I can add unit tests to the library without the unit tests crashing themselves if someone screws up. – NomenNescio Sep 21 '12 at 13:32
  • From you question it seemed you only had a problem of using ::new and ::delete before the memory management is initialized. If you want to use both, you'll have to explicitly call the new/delete you want to test. If the library designers don't use a namespace for that you might be in trouble, since you don't know what method they call internally in their library. – count0 Sep 21 '12 at 13:34
0

if overriding is done with a macro you may use

#pragma push_macro ("new")
#undef new
...code with standard new here ...
#pragma pop_macro ("new")

If it is really done by function override then you may temporarily construct a "new" macro yourself that calls a function with another name placed elsewhere which just calls the standard function. Macros are resolved before function calls.

Ole Dittmann
  • 1,764
  • 1
  • 14
  • 22