ProgramlamaC Geliştirici

C dilinde işlevlere dizi iletme mekanizması hakkında ayrıntılı bilgi verin. Bu modelle ilgili riskler nelerdir ve işlevler içinde dizilerle güvenli bir şekilde çalışmayı nasıl organize edebilirsiniz?

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

Cevap

C dilinde diziler işlevlere değer ile iletilmez. Bir diziyi argüman olarak ilettiğinizde, işlev aslında dizinin ilk elemanının işaretçisini alır. Bu, işlevin dizinin kopyasını değil, orijinal diziyi değiştirmesine neden olur.

Örneğin:

void fillArray(int arr[], int n) { for (int i = 0; i < n; ++i) arr[i] = i*i; } int main() { int myarr[5]; fillArray(myarr, 5); // tamam }

İşlev içinde:

  • sizeof(arr) ile orijinal dizinin boyutunu öğrenmek mümkün değildir — bu, işaretçinin boyutunu döndürür, dizinin boyutunu değil.
  • Sadece açıkça belirttiğimiz bellek kısmı ile çalışabiliriz.

Dizilerle güvenli bir şekilde ve doğru bir şekilde çalışmak için şunları yapın:

  • dizinin boyutunu ayrı bir argüman olarak her zaman açıkça iletin;
  • boyutlar için sabitler veya makro sarıcılar kullanın;
  • diziyi değişikliklerden korumak istiyorsanız, const int *arr ile iletin.

Şaşırtıcı Soru

Soru: İşlev içinde int arr[] argümanı ile iletilen dizinin boyutunu sizeof(arr) kullanarak öğrenmek mümkün mü?

Cevap: Hayır, mümkün değil! İşlev içinde sizeof(arr) işaretçinin boyutunu dönecektir (örneğin, 4 veya 8 byte), dizinin boyutunu değil.

Örnek:

void f(int arr[]) { printf("%zu\n", sizeof(arr)); // işaretçinin boyutu, dizinin değil! } int main() { int x[10]; f(x); // Genellikle 8 (x86_64) veya 4 (x86) yazdırır }

Gerçek Hata Örnekleri


Hikaye

Endüstriyel bir projede dizi kopyalama işlevleri, işlev içinde sizeof(arr)/sizeof(int) kullanarak dizinin uzunluğunu anlık olarak hesaplamaya çalıştılar. Bu durumda bu, dizinin boyutunun her zaman 1 (8/8) olduğu anlamına geliyordu ve veriler öngörülemez bir şekilde üzerine yazılıyordu.


Hikaye

Bir ağ uygulamasında veri gönderme işlevi, boyutunu açıkça belirtmeden bir dizi olarak bir tampon aldı, bu nedenle tüm tampon gönderilemedi veya tamponun sınırları dışında çöp okumalar yapıldı, bu da iletim hatalarına ve bağlantı istikrarsızlığına neden oldu.


Hikaye

Görüntülerle çalışmak için bir kütüphane yazarken, programcı görüntü dizisini boyut zorunlu parametresi olmadan renklendirme işlevini sağlamadı. Bu, bellek taşmasına ve belirli girdilerde programın çökmesine neden oldu, bu da yalnızca büyük bir görüntüde entegrasyon testinde keşfedildi.