ProgramlamaBackend C geliştiricisi

Bellek kopyalamanın C dilinde güvenli bir şekilde nasıl gerçekleştirileceğini, hangi standart kütüphane işlevlerinin kullanılacağını ve bunların farkını açıklayın.

Hintsage yapay zeka asistanı ile mülakatları geçin

Cevap

Soru tarihçesi

Güvenli bellek kopyalama, C'deki en yaygın ve kritik görevlerden biridir. İlk başta programlar, her bir baytın kopyalanması için döngüler kullanıyordu. Daha sonra standart işlevler eklendi: memcpy, memmove ve daha korumalı alternatifler, örneğin dizeler için strncpy. Yanlış kopyalama, tampon taşmalarına ve güvenlik açıklarına yol açar.

Sorun

Yanlış işlevin veya kopyalamada hata boyutunun kullanılması, verilerin bozulmasına veya hatta güvenlikle ilgilenen kötü niyetli kişilere açılan bir kapı oluşturabilir. memmove ve memcpy kullanıldığında hangi durumların ayırt edilmesi gerektiğini bilmek, bellekteki örtüşen alanlarla ilgili hatalardan kaçınmak için hayati önem taşır.

Çözüm

Dize olmayan belleği güvenli bir şekilde kopyalamak için şunları kullanın:

memcpy(dest, src, n);
  • memcpy, src'den dest'e n baytı hızlı bir şekilde kopyalar, eğer bellek alanları örtüşmüyorsa.
  • Eğer alanlar örtüşüyorsa, memmove kullanın:
memmove(dest, src, n);

Dizeleri kopyalamak için ya strncpy ya da daha modern ve korumalı alternatifler mevcutsa, strlcpy kullanmak daha iyidir.

Ana özellikler:

  • memcpy, src ve dest arasında örtüşme olmadığında güvendir.
  • memmove, örtüşen bellek alanlarıyla bile doğru çalışır.
  • Dizeler için, sıfır terminatörünü dikkate alarak, özel işlevlerin kullanılması daha iyidir.

Kandırmaca soruları.

1. memcpy ile memmove arasındaki fark nedir ve hangi durumlarda hangi işlev gereklidir?

memcpy çok hızlı çalışır, ancak örtüşen bellek alanları için uygun değildir — sonuç tahmin edilemez hale gelir. memmove, örtüşme olup olmadığına bakılmaksızın doğru kopyalamayı garanti eder:

int arr[] = {1,2,3,4,5}; // memmove: örtüşmeyle güvenli bir şekilde kopyalıyoruz memmove(arr+1, arr, 4 * sizeof(int));

2. string kopyalamak için strcpy kullanmak güvenli midir?

Hayır, strcpy işlevi hedef tamponun boyutunu kontrol etmez. Bu sıklıkla tampon taşmasına yol açar. Daha iyi bir alternatif olarak strncpy veya varsa strlcpy kullanmak veya boyutu açıkça kontrol etmek daha iyidir:

char dest[5]; strncpy(dest, src, sizeof(dest)-1); // src 5 karakterden daha kısa olmalıdır

3. Yapıları işaretçiler ile kopyalamak için memcpy kullanabilir miyiz?

Evet, ancak bu yalnızca işaretçileri kopyalar, o adreslerdeki verileri değil. Bu, bellekle çalışırken hatalara ve çift serbest bırakmalara neden olabilir.

Yaygın hatalar ve anti-patentler

  • Bellek alanlarının örtüşmesi durumunda memcpy kullanmak.
  • Hedef tamponun boyutunu dikkate almamak.
  • İçinde işaretçilerin bulunduğu yapıların basit memcpy ile kopyalanması (shallow copy).

Gerçek hayattan bir örnek

Olumsuz durum

Uzun bir dizenin uzunluğu kontrol edilmeden küçük bir tampona strcpy ile kopyalanması. Tampon taşması meydana gelir ve bu bir güvenlik açığına yol açar.

Artıları:

  • Minimum kod, hızlı çalışma.

Eksileri:

  • Güvenlik açığı, olası çökme, bellek bozulması.

Olumlu durum

Boyutu dikkatlice kontrol eden strncpy veya memmove kullanılır, dizenin sonuna sıfır terminatörünün eklenmesi sağlanır.

Artıları:

  • Tahmin edilebilir davranış, tampon taşmasından korunma.

Eksileri:

  • Uzunluğun kontrol edilmesi gerektiği için ek bir denetim gerektirir ve belki de ek kontroller nedeniyle hızda küçük bir düşüşe neden olabilir.