How can I decide if there can be more than one VC ++ CRT state for my application?

This MSDN article says that if my application loads VC ++ runtime several times because either it or some of the DLLs it depends on is statically linked to VC ++ runtime, then the application will have several CRT states, and this may lead to undefined behavior.

How exactly do I decide if this is a problem for me? For example, this MSDN article presents several examples that basically say that objects supported by the C ++ runtime, such as file descriptors, should be passed across the borders of the DLL. What is a list of things to check if I want my Was the project statically linked to the VC ++ runtime?

+4
source share
7 answers

It's OK to have multiple copies of a CRT if you are not doing certain things ...:

Each CRT copy will manage its own heap.

This can cause unforeseen problems if you select an object with a heap in module A using "new" and then pass it to module B, where you are trying to free it using "delete". The CRT for module B will try to identify the pointer in terms of its own heap and that where undefined behavior occurs: if you are lucky, the CRT in module B will detect a problem and you will get a heap error. If you're unlucky, something strange will happen and you won't notice it until much later ...

You will also have serious problems if you pass other CRT-driven things, such as files between modules.

If all your modules dynamically reference CRT, then all of them will share the same heap, and you can go around everything and not worry about where they are deleted.

If you statically bind a CRT in each module, then you need to make sure that your interfaces do not include these types, and that you do not allocate using the "new" or malloc in one module, and then try to clean it in another.

You can get around this limitation by using an OS allocation function such as MS Windows GlobalAlloc () / GlobalFree (), but this can be a pain as you need to keep track of which distribution scheme you used for each pointer.

If you need to worry about whether there is a CRT DLL on the target machine that your modules require or pack it with your application, this can be a pain, but it is a one-time pain - and once you don’t need to worry about everything, what was said above.

+2
source

This does not mean that you cannot pass CRT descriptors. This means that you must be careful when you have two modules that read / write a descriptor.

For example, in dll A you write

char* p = new char[10]; 

and in the main program write

  delete[]p; 

When dll A and your main program have two CRTs, new delete operations will be performed in different heaps. The heap in the DLL cannot manage the heap in the main program, resulting in memory leaks.

Same thing in the file descriptor. An internal file descriptor may have different implementations in addition to a memory resource. Calling fopen in one module and calling fwrite and fclose in another case can lead to problems, because FILE * data points may be different during CRT execution.

But you can, of course, pass FILE * or a memory pointer between two modules.

+1
source

One of the problems that I have encountered with different versions of the MSVC bootable environment is that each runtime has its own heap, so you can end up distributing failures with "out of memory" even if there is a lot of memory available, but in the wrong heap.

0
source

The main problem is that problems can occur at runtime. At the binary level, you have DLLs that invoke function calls, eventually in the OS. Calls alone are good, but there are no arguments at run time. Of course, this may depend on the exact code paths.

Worse, it can even be time or machine dependent. An example of this would be a shared resource used by two DLLs and protected by an appropriate reference counter. The last user will delete it, which may be the DLL that created it (lucky) or another (problem)

0
source

As far as I know, there is no (safe) way to check which version of the CRT library is statically linked to.

However, you can verify binary files with a program such as DependencyWalker . If you do not see DLL files starting with MSVC in the list of dependencies, they are most likely statically linked. If the library is from the third part, I would simply assume that it uses a different version of CRT. Of course, this is not 100% accurate, because the library you are looking at may be linked to another library that is linked to a CRT.

0
source
  • if CRT descriptors are a problem, then do not expose CRT descriptors in your dll export :-)
  • don't skip memory pointers (if the exported class allocates some memory, it should free it ... which means you are not entering the built-in constructor / destructor?)
0
source

This MSDN article ( here ) states that you must be changed to LNK4098 linker error. It also suggests that passing any CRT descriptors across the CRT boundary can cause problems and mentions local, low-level I / O and memory allocation files as examples.

0
source

All Articles