Does a C++ shared library have its own memory space? Or does it share the caller process' one?
I have a shared library which contains some classes and wrapper functions.
One of this wrapper function is kinda:
libXXX_construct()
which initializes an object and returns the pointer to the said object.
Once I use libXXX_construct()
in a caller program where is the object placed?Is it in the "caller" memory space or is it in the library's memory space?
A linked instance of the shared library shares the memory space of the instance of the executable that linked to it, directly or indirectly. This is true for both Windows and the UN*X-like operating systems. Note that this means that static variables in shared libraries are not a way of inter-process communication (something a lot of people thinks).
All the shared libraries share the virtual memory space of their process. (Including the main executable itself)
Unless specified otherwise, a shared library will share memory with the process hosting it. Each process instance will then have its own copy.
However, on Windows it is possible to create shared variables which allow inter-process communication. You do so by putting them in the right kind of segment. By default Windows uses two kinds of segments: data segments are read/write unshared, whereas code segments are read-only executable and shared. However, the read-write and shared attributes are orthogonal. A shared read-write segment in a library can be used to store shared variables, and it will survive until the last process exits.
Be careful with C++, as that will happily run constructors and destructors on process start & exit, even if you put variables in shared segments.
For details, see Peering Inside the PE: A Tour of the Win32 Portable Executable File Format part 2 by Matt Pietrek.
The shared library has the same address space as its host process. It has to be that way, or else you wouldn't be able to pass pointers from one module to another since they wouldn't be able to dereference them.
But although they are in the same address space, that doesn't mean they all use the same memory manager. The consequence is that if you provide a function that allocates memory on behalf of the caller, then you should provide a corresponding function to free that memory, say, libXXX_destroy()
.
Your object exists in the caller's memory space (in fact the one memory space shared between the library and the main executable)
The share address space so you can share pointers, however they don't share allocator (at least not on windows).
This means that if you call new to allocate an object inside a shared library you must call delete inside the same library or strange things may happen.
It's true that a library will use up memory in each process that loads it. However, at least under Windows, when multiple processes load the same DLL, unmodified pages (including all code pages) are quietly shared under the covers. Also, they take up no space in the swap file, since they're backed by the original file.
I believe this is more complicated for .NET, due to JIT compilation, but would still be true for NGENed assemblies.
edit
This is a detail of the VM. However, you can also flag a segment in a DLL to be shared across processes.