Pojďme nejprve pochopit alokaci haldy a zásobník na OS Windows s našimi aplikacemi/DLL. Tradičně operační systém a run-time knihovny přicházejí s implementací haldy.
- Na začátku procesu vytvoří operační systém výchozí haldu s názvem Process halda. Halda Proces se používá pro přidělování bloků, pokud není použita žádná jiná halda.
- Doby běhu jazyka mohou také vytvářet samostatné hromady v rámci procesu. (Například doba běhu jazyka C vytvoří vlastní hromadu.)
- Kromě těchto vyhrazených hald může aplikační program nebo jedna z mnoha načtených dynamických knihoven (DLL) vytvářet a používat samostatné haldy, nazývané soukromé haldy
- Tato halda je umístěna nad správcem virtuální paměti operačního systému ve všech systémech virtuální paměti.
- Pojďme diskutovat více o CRT a souvisejících hromadách:
- C/C++ Runtime (CRT) alokátor:Poskytuje malloc() a free() a také operátory new a delete.
- CRT vytvoří takovou extra haldu pro všechny své alokace (handle této haldy CRT je uložena interně v knihovně CRT v globální proměnné nazvané _crtheap) jako součást své inicializace.
- CRT vytváří svou vlastní soukromou haldu, která je umístěna nad haldou Windows.
- Hroma Windows je tenká vrstva obklopující běhový alokátor Windows (NTDLL).
- Běhový alokátor Windows spolupracuje s virtuálním alokátorem paměti, který rezervuje a odevzdává stránky používané operačním systémem.
Vaše DLL a exe odkazují na vícevláknové statické knihovny CRT. Každá DLL a exe, kterou vytvoříte, má svou vlastní haldu, tj. _crtheap. Alokace a dealokace musí probíhat z příslušné haldy. Že dynamicky alokované z DLL nelze zrušit přidělení ze spustitelného souboru a naopak.
Co můžeš udělat? Zkompilujte náš kód v DLL a exe pomocí /MD nebo /MDd, abyste mohli používat verzi run-time knihovny specifickou pro více vláken a pro DLL. Proto jsou jak DLL, tak exe propojeny se stejnou knihovnou C runtime, a tedy jedním _crtheap. Alokace jsou vždy spárovány s dealokacemi v rámci jednoho modulu.
Knihovny DLL / exe se budou muset propojit s implementací knihoven pro běh C.
V případě C Windows Runtime knihoven máte možnost určit, zda chcete odkazovat na následující:
- Jednovláknová C Runtime knihovna (podpora jednovláknových knihoven byla nyní ukončena)
- Vícevláknová knihovna DLL / Vícevláknová ladění DLL
- Statické knihovny doby běhu.
- Málo dalších (můžete zkontrolovat odkaz)
Každý z nich bude odkazovat na jinou hromadu, takže vám není povoleno předat adresu získanou z hromady jedné runtime knihovny do jiné.
Nyní záleží na tom, se kterou knihovnou C runtime byla propojena DLL, o které mluvíte. Předpokládejme, že knihovna DLL, kterou používáte, byla propojena se statickou knihovnou C runtime a kód vaší aplikace (obsahující hlavní funkci) je propojen s multivláknovou C Runtime DLL, pak pokud předáte ukazatel na paměť přidělenou v DLL do vašeho hlavního programu a pokuste se ji uvolnit tam nebo naopak, může to vést k nedefinovanému chování. Základní příčinou jsou tedy C runtime knihovny. Vybírejte je prosím pečlivě.
Další informace o podporovaných knihovnách doby běhu C naleznete zde a zde
Citace z MSDN:
Pozor Nekombinujte statické a dynamické verze run-time knihoven. Mít více než jednu kopii run-time knihoven v procesu může způsobit problémy, protože statická data v jedné kopii nejsou sdílena s druhou kopií. Linker vám brání v propojení se statickou i dynamickou verzí v rámci jednoho souboru EXE, ale přesto můžete skončit se dvěma (nebo více) kopiemi run-time knihoven. Například dynamicky propojovaná knihovna propojená se statickými (jinými než DLL) verzemi run-time knihoven může způsobit problémy při použití se souborem .exe, který byl propojen s dynamickou (DLL) verzí run-time knihoven. . (Také byste se měli vyvarovat smíchání ladicích a neladících verzí knihoven v jednom procesu.)