Tamam malloc hakkında bazı cevaplar zaten gönderildi.
Daha ilginç olan kısım, nasıl çalıştığıdır (ve bu yönde, malloc da daha iyi anlaşılabilir).
Birçok malloc / free uygulamasında, free normalde belleği işletim sistemine geri döndürmez (veya en azından nadir durumlarda). Bunun nedeni, yığınınızda boşluklar görmeniz ve böylece gerçekleşebilir, 2 veya 4 GB'lık sanal belleğinizi boşluklarla bitirmeniz yeterlidir. Bundan kaçınılmalıdır, çünkü sanal bellek biter bitmez, gerçekten büyük belada olacaksınız. Diğer neden, işletim sisteminin yalnızca belirli bir boyut ve hizalamadaki bellek yığınlarını işleyebilmesidir. Özel olarak belirtmek gerekirse: İşletim sistemi normalde yalnızca sanal bellek yöneticisinin işleyebileceği blokları işleyebilir (çoğunlukla 4KB gibi 512 baytın katları).
Bu yüzden işletim sistemine 40 bayt döndürmek işe yaramaz. Peki özgür ne yapar?
Free, bellek bloğunu kendi serbest blok listesine koyacaktır. Normalde adres alanındaki bitişik blokları birleştirmeye çalışır. Serbest blok listesi, başlangıçta bazı idari verilere sahip olan bellek parçalarının sadece dairesel bir listesidir. Bu ayrıca standart malloc / free ile çok küçük bellek öğelerinin yönetilmesinin etkili olmamasının nedenidir. Her bellek yığının ek verilere ihtiyacı vardır ve daha küçük boyutlarda daha fazla parçalanma olur.
Serbest liste, malloc'un yeni bir bellek yığını gerektiğinde baktığı ilk yerdir. İşletim sisteminden yeni bellek çağırmadan önce taranır. Gerekli hafızadan daha büyük bir yığın bulunduğunda, iki bölüme ayrılır. Biri arayan kişiye geri döner, diğeri tekrar ücretsiz listeye alınır.
Bu standart davranışta birçok farklı optimizasyon vardır (örneğin, küçük bellek parçaları için). Ancak malloc ve free'in bu kadar evrensel olması gerektiğinden, alternatifler kullanılamadığında standart davranış her zaman geri dönüştür. Serbest listenin işlenmesinde optimizasyonlar da vardır - örneğin, parçaları boyutlara göre sıralanmış listelerde saklamak. Ancak tüm optimizasyonların da kendi sınırlamaları vardır.
Kodunuz neden çöküyor:
Bunun nedeni, 4 karakter büyüklüğünde bir alana 9 karakter (sondaki boş bayt unutmayın) yazarak, veri kümenizin "arkasında" bulunan başka bir bellek yığını için depolanan yönetimsel verilerin üzerine yazmanızdır ( çünkü bu veriler çoğunlukla bellek parçalarının "önünde" saklanır). Daha sonra ücretsiz, yığınınızı ücretsiz listeye koymaya çalıştığında, bu yönetimsel verilere dokunabilir ve bu nedenle üzerine yazılmış bir işaretçi üzerinde yanabilir. Bu sistem çökecektir.
Bu oldukça zarif bir davranış. Ben de bir yerde kaçak işaretçi belleksiz listede verilerin üzerine yazdığı ve sistem hemen çökmedi ama bazı alt rutinleri daha sonra durumları gördüm. Orta karmaşıklıkta bir sistemde bile bu tür problemleri ayıklamak gerçekten zor olabilir! Katıldığım bir vakada, çökmenin nedenini bulmamız birkaç gün sürdü (daha büyük bir geliştirici grubu) - çünkü bellek dökümünde belirtilenlerden tamamen farklı bir yerdeydi. Saatli bomba gibi. Biliyorsun, bir sonraki "özgür" veya "malloc" çökecek, ama nedenini bilmiyorsun!
Bunlar en kötü C / C ++ sorunlarından bazıları ve işaretçilerin bu kadar sorunlu olmasının bir nedeni.