Menu
Coddy logo textTech

calloc() ile Bellek Ayırma

Coddy'nin C Journey'sinin Logic & Flow bölümünün bir parçası — ders 36 / 63.

malloc() dinamik bellek ayırma için en yaygın fonksiyon olsa da, C başka bir kullanışlı alternatif sunar: calloc(). "Bitişik ayırma" (contiguous allocation) anlamına gelen calloc() fonksiyonu, önemli bir ek avantajla birlikte diziler için bellek ayırmanın kolay bir yolunu sunar.

Tek bir argüman (toplam bayt) alan malloc() fonksiyonunun aksine, calloc() iki argüman alır: tahsis etmek istediğiniz eleman sayısı ve her bir elemanın boyutu. Bu, özellikle dizilerle çalışırken onu sezgisel hale getirir. Örneğin:

#include <stdlib.h>

// calloc() kullanarak 5 tam sayı için yer ayırın
int *arr = (int*)calloc(5, sizeof(int));

// Bu şuna eşdeğerdir: malloc(5 * sizeof(int))

calloc() fonksiyonunun temel avantajı, ayrılan tüm belleği otomatik olarak sıfıra ilklendirmesidir. malloc() kullandığınızda, ayrılan bellek daha önce orada saklanan rastgele değerleri içerir, ancak calloc() her baytın sıfıra ayarlanmasını garanti eder. Bu, tüm tamsayıların 0, tüm kayan noktalı sayıların 0.0 ve tüm işaretçilerin NULL olacağı anlamına gelir.

malloc() gibi, calloc() da ayrılan belleğe bir işaretçi döndürür veya ayırma başarısız olursa NULL döndürür; bu nedenle her zaman ayırma hatasını kontrol etmeli ve kullanmayı bitirdiğinizde belleği free() etmeyi unutmamalısınız.

challenge icon

Görev

Kolay

Otomatik sıfır başlatma ile dinamik bellek tahsisi için calloc() kullanımını gösteren bir C programı yazın. Programınız şunları yapmalıdır:

  1. Kullanıcıdan tahsis edilecek tam sayı adedini temsil eden bir size tam sayısı okuyun
  2. size adet tam sayıdan oluşan bir dizi için dinamik olarak bellek tahsis etmek üzere calloc() kullanın
  3. Bellek tahsisinin başarılı olup olmadığını kontrol edin - başarısız olursa, Memory allocation failed! yazdırın ve programı sonlandırın
  4. Tahsis başarılı olursa, Memory allocated and initialized to zero! yazdırın
  5. Dizideki tüm başlangıç değerlerinin sıfır olduğunu göstermek için şu formatta yazdırın: Initial values: [value1] [value2] [value3] ...
  6. Kullanıcıdan size adet tam sayı değeri okuyun ve bunları tahsis edilen dizide saklayın
  7. Tüm güncellenmiş değerleri şu formatta yazdırın: Updated values: [value1] [value2] [value3] ...
  8. Tüm değerlerin toplamını hesaplayın ve şu formatta yazdırın: Sum: [value]
  9. Belleği serbest bırakmak için free() kullanın
  10. Temizliği onaylamak için Memory freed! yazdırın

calloc() ve free() kullanmak için <stdlib.h> başlık dosyasını dahil etmeyi unutmayın. Bu zorluk, calloc()'un malloc()'a göre temel avantajını gösterir: tahsis edilen tüm belleğin otomatik olarak sıfıra başlatılması.

Örneğin, giriş şu şekildeyse:

3
10 20 30

Çıktınız şu şekilde olmalıdır:

Memory allocated and initialized to zero!
Initial values: 0 0 0
Updated values: 10 20 30
Sum: 60
Memory freed!

Bu zorluk, calloc()'un dinamik olarak tahsis edilen dizileriniz için nasıl temiz ve öngörülebilir bir başlangıç durumu sağladığını, malloc()'un geride bırakabileceği öngörülemeyen çöp değerleri (garbage values) nasıl ortadan kaldırdığını vurgular.

Kopya kağıdı

calloc() fonksiyonu, otomatik sıfır ilklendirmesi ile dinamik bellek tahsisi sağlar.

Sözdizimi:

void* calloc(size_t num_elements, size_t element_size);

malloc() fonksiyonundan temel farklar:

  • İki argüman alır: eleman sayısı ve her bir elemanın boyutu
  • Tahsis edilen tüm belleği otomatik olarak sıfıra ilklendirir
  • Dizi tahsisi için daha sezgiseldir

Örnek kullanım:

#include <stdlib.h>

// calloc() kullanarak 5 tam sayı için yer ayır
int *arr = (int*)calloc(5, sizeof(int));

// Bu şuna eşdeğerdir: malloc(5 * sizeof(int))
// Ancak tüm değerlerin 0 olması garanti edilir

malloc() gibi, calloc() da tahsis edilen belleğe bir işaretçi döndürür veya tahsis başarısız olursa NULL döndürür. Her zaman tahsis hatasını kontrol edin ve işiniz bittiğinde belleği serbest bırakmak için free() kullanın.

Kendin dene

#include <stdio.h>
#include <stdlib.h>

int main() {
    int size;
    
    // Dizinin boyutunu oku
    scanf("%d", &size);
    
    // TODO: Kodunuzu aşağıya yazın
    // Dizi için bellek ayırmak üzere calloc() kullanın
    // Bellek ayırma işleminin başarılı olup olmadığını kontrol edin
    // Başlangıç değerlerini yazdırın (sıfır olmalı)
    // Giriş değerlerini okuyun ve saklayın
    // Güncellenmiş değerleri yazdırın
    // Toplamı hesaplayın ve yazdırın
    // Ayrılan belleği serbest bırakın
    
    return 0;
}
quiz iconKendini test et

Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.

Logic & Flow bölümündeki tüm dersler