Pertama mari kita pahami alokasi heap dan stack pada OS Windows dengan aplikasi/DLL kita. Secara tradisional, sistem operasi dan perpustakaan run-time hadir dengan implementasi heap.
- Di awal proses, OS membuat heap default yang disebut Process heap. Tumpukan Proses digunakan untuk mengalokasikan blok jika tidak ada tumpukan lain yang digunakan.
- Waktu pengoperasian bahasa juga dapat membuat tumpukan terpisah dalam suatu proses. (Misalnya, waktu proses C membuat tumpukannya sendiri.)
- Selain heap khusus ini, program aplikasi atau salah satu dari banyak pustaka tautan dinamis (DLL) yang dimuat dapat membuat dan menggunakan heap terpisah, yang disebut heap pribadi
- Tumpukan ini berada di atas Pengelola Memori Virtual sistem operasi di semua sistem memori virtual.
- Mari kita bahas lebih lanjut tentang CRT dan heap terkait:
- C/C++ Run-time (CRT) allocator:Menyediakan malloc() dan free() serta operator baru dan hapus.
- CRT membuat heap ekstra untuk semua alokasinya (pegangan heap CRT ini disimpan secara internal di library CRT dalam variabel global yang disebut _crtheap) sebagai bagian dari inisialisasinya.
- CRT membuat heap pribadinya sendiri, yang berada di atas heap Windows.
- Tumpukan Windows adalah lapisan tipis yang mengelilingi pengalokasi waktu proses Windows (NTDLL).
- Pengalokasi run-time Windows berinteraksi dengan Pengalokasi Memori Virtual, yang mencadangkan dan menjalankan halaman yang digunakan oleh OS.
Tautan DLL dan exe Anda ke pustaka CRT statis multithreaded. Setiap DLL dan exe yang Anda buat memiliki tumpukannya sendiri, yaitu _crtheap. Alokasi dan de-alokasi harus terjadi dari tumpukan masing-masing. Yang dialokasikan secara dinamis dari DLL, tidak dapat dibatalkan alokasinya dari yang dapat dieksekusi dan sebaliknya.
Apa yang dapat Anda lakukan? Kompilasi kode kami di DLL dan exe menggunakan /MD atau /MDd untuk menggunakan versi run-time library khusus multithread dan khusus DLL. Oleh karena itu baik DLL dan exe ditautkan ke perpustakaan run time C yang sama dan karenanya satu _crtheap. Alokasi selalu dipasangkan dengan de-alokasi dalam satu modul.
DLL / ongkos perlu menautkan ke implementasi perpustakaan run time C.
Dalam hal pustaka C Windows Runtime, Anda memiliki opsi untuk menentukan, jika Anda ingin menautkan ke yang berikut:
- Pustaka C Run time satu utas (Dukungan untuk pustaka satu utas telah dihentikan sekarang)
- DLL multi-utas / DLL Debug multi-utas
- Pustaka waktu Jalankan Statis.
- Lebih Sedikit (Anda dapat memeriksa tautannya)
Masing-masing dari mereka akan merujuk ke heap yang berbeda, jadi Anda tidak diperbolehkan meneruskan alamat yang diperoleh dari heap dari satu library runtime ke library lainnya.
Sekarang, itu tergantung pada perpustakaan run time C mana yang DLL yang Anda bicarakan telah ditautkan. Misalkan katakanlah, DLL yang Anda gunakan telah ditautkan ke pustaka runtime C statis dan kode aplikasi Anda (berisi fungsi utama) telah ditautkan ke C Runtime DLL multi-utas, lalu jika Anda meneruskan penunjuk ke memori yang dialokasikan di DLL ke program utama Anda dan mencoba membebaskannya di sana atau sebaliknya, ini dapat menyebabkan perilaku yang tidak terdefinisi. Jadi, akar penyebab dasarnya adalah pustaka runtime C. Harap pilih dengan hati-hati.
Temukan info lebih lanjut tentang pustaka C run time yang didukung di sini &di sini
Kutipan dari MSDN:
Perhatian Jangan mencampur versi statis dan dinamis dari pustaka run-time. Memiliki lebih dari satu salinan pustaka run-time dalam suatu proses dapat menyebabkan masalah, karena data statis dalam satu salinan tidak dibagikan dengan salinan lainnya. Linker mencegah Anda menautkan dengan versi statis dan dinamis dalam satu file .exe, tetapi Anda masih bisa mendapatkan dua (atau lebih) salinan pustaka run-time. Misalnya, pustaka tautan dinamis yang ditautkan dengan pustaka run-time versi statis (non-DLL) dapat menyebabkan masalah saat digunakan dengan file .exe yang ditautkan dengan versi dinamis (DLL) pustaka run-time . (Anda juga harus menghindari pencampuran versi pustaka debug dan non-debug dalam satu proses.)