0Pricing
C# Academy · Ders

Güvenli Olmayan Kod, İşaretçiler ve Sabit Tamponlar

unsafe anahtar sözcüğünü kullanmayı, işaretçilerle çalışmayı, yönetilen belleği fixed ile sabitlemeyi ve struct'larda sabit boyutlu tamponlara erişmeyi öğrenin.

Güvenli Olmayan Kod, İşaretçiler ve Sabit Tamponlar, CoddyKit'te ücretsiz bir C# Academy dersidir. Bu, 4 dersinin 3. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, C# Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. C# Academy kursu toplamda 4 dersten oluşur.

Güvenli Olmayan Kod Nedir?

C#'ın güvenli olmayan anahtar sözcüğü, doğrudan bellek işlemlerini etkinleştirir: ham işaretçiler, işaretçi aritmetiği ve sabit boyutlu arabellekler. Bu sözcük, çöp toplayıcının güvenlik garantilerini devre dışı bırakır. Proje dosyanızda <AllowUnsafeBlocks>true</AllowUnsafeBlocks> ile etkinleştirin.

// Must add to .csproj:
// <AllowUnsafeBlocks>true</AllowUnsafeBlocks>

// Unsafe blocks can appear inside methods:
unsafe
{
    int x = 42;
    int* ptr = &x;          // get address of x
    Console.WriteLine(*ptr); // dereference — prints 42
    *ptr = 100;
    Console.WriteLine(x);    // 100 — x was mutated via pointer
}

C#'ta İşaretçi Türleri

İşaretçi söz dizimi C/C++'ı andırır: T*, T türüne işaret eden bir işaretçidir. Yönetilmeyen değer türlerine (int, kayan noktalı türler ve başvuru alanı olmayan yapılar) işaretçiler tanımlayabilirsiniz. Yönetilen türlere işaretçi tanımlanmasına izin verilmez.

unsafe
{
    int    i = 10;
    double d = 3.14;

    int*    ip = &i;
    double* dp = &d;

    // Dereference with *
    Console.WriteLine(*ip); // 10

    // Pointer arithmetic — move to next int in memory
    int[] arr = { 1, 2, 3 };
    fixed (int* p = arr)
    {
        Console.WriteLine(*(p + 0)); // 1
        Console.WriteLine(*(p + 1)); // 2
        Console.WriteLine(*(p + 2)); // 3
    }
}

fixed Bildirimi

Yönetilen nesnelerin konumu çöp toplayıcı tarafından değiştirilebilir. Yönetilen bir nesnenin adresini almak için onu sabitlemeniz gerekir; bunun için fixed kullanılır. Çöp toplayıcı, fixed bloğu boyunca nesneyi taşımaz.

byte[] buffer = new byte[256];

unsafe
{
    fixed (byte* pBuf = buffer)
    {
        // pBuf is valid only inside this block
        // GC won't relocate 'buffer' here
        for (int i = 0; i < buffer.Length; i++)
            pBuf[i] = (byte)i;
    }
    // After 'fixed', GC can move 'buffer' again
}

Console.WriteLine(buffer[5]); // 5

İşaretçi Aritmetiği

İşaretçilerden tamsayı ekleyebilir veya çıkarabilirsiniz. Bir int* işaretçisine 1 eklemek, işaretçiyi 4 bayt ilerletir (int türünün boyutu). Bu, hızlı toplu bellek işlemlerinin temelidir.

unsafe
{
    int[] data = { 10, 20, 30, 40, 50 };
    fixed (int* start = data)
    {
        int* p = start;
        long sum = 0;
        for (int i = 0; i < data.Length; i++)
        {
            sum += *p;
            p++;    // advance by sizeof(int) = 4 bytes
        }
        Console.WriteLine(sum); // 150

        // Or with index syntax:
        Console.WriteLine(start[2]); // 30
    }
}

stackalloc: Yığın Üzerinde Ayırma

stackalloc, öbek yerine yığın üzerinde bir bellek bloğu ayırır. Çöp toplayıcı yükü oluşturmaz ve sabitleme gerektirmez. Geçerli yöntemin yığın çerçevesiyle sınırlıdır; yöntem döndüğünde bellek otomatik olarak serbest bırakılır.

// Stack-allocated buffer — zero heap allocation
Span<int> buffer = stackalloc int[128]; // safe Span wrapper
buffer.Fill(0);
buffer[0] = 42;
Console.WriteLine(buffer[0]); // 42

// Or raw pointer form (requires unsafe):
unsafe
{
    int* raw = stackalloc int[128];
    raw[0] = 99;
    Console.WriteLine(raw[0]); // 99
}
// Stack frame popped — memory gone

Yapılarda Sabit Boyutlu Arabellekler

Sabit boyutlu arabellek, sabit uzunluklu bir diziyi yapı içine satır içi olarak yerleştirir; öbek üzerinde bellek ayırmaz ve ek işaretçi gerektirmez. unsafe bağlamında tanımlanan bir yapının içinde fixed değiştiricisini kullanın.

unsafe struct NetworkPacket
{
    public int  Length;
    public byte Command;
    public fixed byte Payload[256]; // 256 bytes inline in the struct
}

unsafe
{
    NetworkPacket pkt;
    pkt.Length  = 10;
    pkt.Command = 0x01;

    // Fill payload inline — no heap allocation
    for (int i = 0; i < 10; i++)
        pkt.Payload[i] = (byte)i;

    Console.WriteLine(pkt.Payload[5]); // 5
}
// sizeof(NetworkPacket) = 4 + 1 + 256 = ~261 bytes on stack

void* ve Tür Dönüştürme

void*, türsüz bir işaretçidir ve genel bellek işlemleri için kullanışlıdır. Başvurusunu kaldırmadan önce türü belirlenmiş bir işaretçiye dönüştürmeniz gerekir. sizeof(T) işleci, güvenli olmayan bağlamda yönetilmeyen türlerle çalışır.

unsafe
{
    int value = 42;
    void* vp = &value;      // typeless pointer
    int*  ip = (int*)vp;    // cast back to int*
    Console.WriteLine(*ip); // 42

    // sizeof works on unmanaged types
    Console.WriteLine(sizeof(int));    // 4
    Console.WriteLine(sizeof(double)); // 8
    Console.WriteLine(sizeof(long));   // 8
}

MemoryMarshal ve Unsafe Sınıfı

System.Runtime.CompilerServices.Unsafe ve System.Runtime.InteropServices.MemoryMarshal, düşük düzeyli işlemlerin çoğu için güvenli (anahtar sözcük kullanmayan) alternatifler sunar; Span ile uyumludur ve unsafe anahtar sözcüğü kullanılmadan kullanılabilir.

using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// Reinterpret a Span<byte> as Span<int> — no copy, no unsafe keyword
byte[] raw = new byte[16];
Span<int> ints = MemoryMarshal.Cast<byte, int>(raw);
ints[0] = 12345678;
Console.WriteLine(ints[0]); // 12345678

// Unsafe.As<,> — reinterpret reference type (advanced)
ref int first = ref MemoryMarshal.GetReference(ints);
Unsafe.Add(ref first, 1) = 99999;
Console.WriteLine(ints[1]); // 99999

Güvenli Olmayan Kod Ne Zaman Kullanılmalı

Güvenli olmayan kodu yalnızca açık bir performans gereksinimi olduğunda ve güvenli bir alternatif bulunmadığında kullanın. Güvenli olmayan kodun kapsamını sınırlı tutun; bunu özel yardımcı yöntemlere veya ayrılmış türlere yalıtın. Kapsamlı testler yazın ve varsayımları belgeleyin.

// GOOD: narrow unsafe scope
public static unsafe int SumBytes(ReadOnlySpan<byte> data)
{
    int total = 0;
    fixed (byte* p = data)
    {
        byte* end = p + data.Length;
        for (byte* cur = p; cur < end; cur++)
            total += *cur;
    }
    return total;
}

// BETTER for modern code: use SIMD via Vector<T> or hardware intrinsics
// which stay in managed code but still achieve native-level perf

Gerçek Dünya: İkili Protokolü Ayrıştırma

Güvenli olmayan işaretçiler ve sabit boyutlu arabellekler, yapı düzeninin bir kablo biçimiyle tam olarak eşleşmesi gereken ikili protokolleri ayrıştırırken büyük avantaj sağlar. Yapı, bir bayt arabelleğinden directly olarak dönüştürülebilir ve hiç kopyalama yapılmaz.

[StructLayout(LayoutKind.Sequential, Pack = 1)]
unsafe struct MessageHeader
{
    public uint  Magic;        // 4 bytes
    public ushort Version;    // 2 bytes
    public ushort PayloadLen; // 2 bytes
    public fixed byte Id[16]; // 16 bytes GUID inline
}

unsafe ReadOnlySpan<byte> SerializeHeader(MessageHeader hdr)
{
    // Cast struct directly to bytes — zero copy
    return new ReadOnlySpan<byte>(&hdr, sizeof(MessageHeader));
}

unsafe MessageHeader ParseHeader(ReadOnlySpan<byte> buf)
{
    fixed (byte* p = buf)
        return *(MessageHeader*)p; // reinterpret cast
}

Hızlı Kontrol

Yönetilen bir nesnenin adresini alırken fixed bildirimi neden gereklidir?

Özet: Güvenli Olmayan Kod, İşaretçiler ve Sabit Arabellekler

Önemli çıkarımlar:

  • unsafe anahtar sözcüğü ham işaretçileri etkinleştirir; projede AllowUnsafeBlocks gerektirir
  • fixed bildirimi, çöp toplayıcının yönetilen nesnelerin konumunu değiştirmemesi için onları sabitler
  • İşaretçi aritmetiği bayt sayısına göre değil, öğe boyutuna göre ilerler
  • stackalloc, yığın üzerinde bellek ayırır; çöp toplayıcı yükü oluşturmaz ve yöntem sona erdiğinde serbest bırakılır
  • Sabit boyutlu arabellekler (fixed byte Payload[N]), dizileri yapıların içine satır içi olarak yerleştirir
  • Çoğu senaryoda Span<T>, MemoryMarshal ve Unsafe sınıfını tercih edin

Sıkça Sorulan Sorular

“Güvenli Olmayan Kod, İşaretçiler ve Sabit Tamponlar” dersi ücretsiz mi?

Evet — “Güvenli Olmayan Kod, İşaretçiler ve Sabit Tamponlar” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve C# Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. C# Academy kursu toplamda 4 dersten oluşur.

“Güvenli Olmayan Kod, İşaretçiler ve Sabit Tamponlar” dersinde ne öğreneceğim?

unsafe anahtar sözcüğünü kullanmayı, işaretçilerle çalışmayı, yönetilen belleği fixed ile sabitlemeyi ve struct'larda sabit boyutlu tamponlara erişmeyi öğrenin. C# Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

C# Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te C# Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 3. dersidir.

“Güvenli Olmayan Kod, İşaretçiler ve Sabit Tamponlar” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu C# Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her C# Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. P/Invoke Temelleri
  2. LibraryImport ve Kaynak Tarafından Oluşturulan P/Invoke
  3. Güvenli Olmayan Kod, İşaretçiler ve Sabit Tamponlar
  4. COM Birlikte Çalışabilirliği ve Çalışma Zamanı Çağrılabilir Sarmalayıcıları
← C# Academy Sayfasına Dön