«Управление памятью», как правило, является разделенной ответственностью. ОС передает адресное пространство большими кусками во время выполнения, которое затем передает его меньшими битами программе. Это адресное пространство может иметь или не иметь выделенную оперативную память. (Если нет, там будет место подкачки, чтобы поддержать его)
Обычно, когда загружается DLL, Windows выделяет адресное пространство для кода и сегментов данных и вызывает DllMain()
. Компилятор C ++ организует вызов глобальных ctors из DllMain()
. Если это DLL, написанная на C ++, она, вероятно, будет зависеть от DLL времени выполнения C ++, которая, в свою очередь, будет зависеть от Kernel32.DLL и User32.DLL. Windows понимает такие зависимости и организует их загрузку в правильном порядке.
Существует только одно адресное пространство для проверки, поэтому DLL получит доступ ко всей памяти процесса. Если DLL загружена в двух процессах, будет две логические копии кода и данных. (хотя копии кода и данные только для чтения могут использовать одну и ту же физическую память).
Если DLL выделяет память с помощью функций ОС, Windows выделяет память для процесса, из которого DLL произвела это выделение. Процесс должен вернуть память, но любой код в процессе может это сделать. Если ваша DLL выделяет память с помощью функций C ++, она будет делать это, вызывая operator new
в DLL времени выполнения C ++. Эта память должна быть возвращена путем вызова operator delete
в (той же самой) C ++ DLL времени выполнения. Опять же, не имеет значения, кто это делает.
Классы STL, такие как vector<>
, могут быть многократно созданы, но это не имеет значения, если вы используете один и тот же компилятор. Все экземпляры будут по существу равны, и все вернут память вектора к одной и той же функции освобождения.
В этом объяснении есть 2 основных предположения:
- EXE и его библиотеки DLL скомпилированы одним и тем же компилятором
- Все EXE-файлы и их библиотеки DLL связаны с динамической библиотекой C ++ (то есть статически не связаны)
Статическое связывание со средой выполнения C ++ полезно, если вы хотите загрузить один автономный EXE-файл. Но если вы уже отправляете библиотеки DLL, вы должны также сохранить среду выполнения C ++ в своей собственной библиотеке DLL.