How to get a global var that will be created as the first thing in C ++ under win32?

sI'm on Windows, and I'm building a C ++ project with VS2008. I am trying to replace new / delete / malloc / free etc. What works, that is, my replacements cause.

However, my replacement allocator must be initialized. I have done this so far, defining it as a global variable in the C # pragma init_seg (lib) .cpp file defined inside it.

This worked until recently, when std :: locale started initializing, which called a new one before my allocator initialized. So I nervously moved my global distributor variable to the compiler segment, i.e. #pragma init_seg (compiler).

This worked a bit and I decided to override malloc. Now I get a malloc call in __crtGetStringTypeA_stat in _tmainCRTStartup, which before even global vars in the compiler segment were initialized.

Is it possible to instantiate my variable before running CRT. The only thing I can think of is to rebuild my crt lib and try some ways to insert my initialization code wherever. I suppose there should also be a crt cleanup function?

Is there an easier way to do this and / or something obvious that I'm missing here?

+4
source share
2 answers

You are using a static storage duration object.

But you are having problems with the initialization order.
To solve this problem, use a static storage duration object that is defined within the scope.

 MyAllocator& getAllocator() { static MyAllocator allocator; // Note the static here. // It has the appropriate lifespan and will be destoryed. // and is automatically constructed the first time this // function is called. return allocator; } 

Now your versions of new / delete / etc can get a reference to the dispenser by calling getAllocator (). This ensures that the object is correctly initialized (provided that MyAllocator has the correct constructor).

+5
source

In windows, you can use InitOnceExecuteOnce to initialize the dispenser. For instance:

 static INIT_ONCE initFlag = INIT_ONCE_STATIC_INIT; static BOOL CALLBACK InitMyHeap(PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context) { *Context = (PVOID)CreateMyHeap(); } MyHeap *GetMyHeap() { PVOID vpMyHeap; if (!InitOnceExecuteOnce(&initFlag, InitMyHeap, NULL, *vpMyHeap)) { abort(); } return (MyHeap *)vpMyHeap; } 

In this case, your heap will be initialized exactly once, after calling GetMyHeap() . Then your overrides new / delete / malloc should call GetMyHeap() to get a pointer to the heap structure (or just to ensure the heap is initialized). This is safe even with multiple threads, and even if it happens before CRT initialization, since initFlag is static data in your data segment and does not require a constructor call.

Note that CreateMyHeap() must be careful not to use CRT services; directly access the functions of the Windows DLL (i.e. kernel32.dll and friends).

+1
source

All Articles