ProgramlamaC Geliştirici

Bir yapıyı değeriyle bir fonksiyona ilettiğimizde ne olur ve bu, programın performansını ve semantiğini nasıl etkiler?

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

Cevap

C dilinde bir yapıyı değeriyle bir fonksiyona ilettiğinizde, yapının tam bir kopyası geçici bellek alanında (genellikle fonksiyon yığını üzerinde) oluşturulur. Bu, fonksiyon içindeki herhangi bir değişikliğin, fonksiyon dışında orijinal yapı örneğini etkilemeyeceği anlamına gelir.

Büyük yapıları değeriyle ilettiğinizde, tüm yapının üyelerinin kopyalanması gerekliliği sebebiyle zaman ve bellek maliyetleri ile karşılaşırsınız. Bu nedenle, standart uygulama yapının bir göstericisini iletmektir:

#include <stdio.h> struct Data { int arr[1000]; int flag; }; void modify_by_value(struct Data d) { d.flag = 10; // Sadece yerel kopyayı değiştirir } void modify_by_pointer(struct Data *d) { d->flag = 20; // Orijinali değiştirir } int main() { struct Data data = { {0}, 0 }; modify_by_value(data); // data.flag == 0 modify_by_pointer(&data); // data.flag == 20 return 0; }

Gösterici ile geçirmenin avantajları:

  • Büyük veri hacminin kopyalanması için maliyet yok
  • Orijinal yapıyı değiştirebilirsiniz

Değer ile geçirmenin dezavantajları:

  • Kopyalama için zaman ve bellek maliyetleri
  • Yüksek yığın tüketimi (özellikle mikrodenetleyicilerde)

Kandırmaca Soru

Bir fonksiyon değeriyle yapı döndürdüğünde ne olur? Hangi riskler vardır?

Cevap:

C dilinde, bir fonksiyondan yapıyı değeriyle döndürmek mümkündür, örneğin:

struct Point { int x, y; }; struct Point make_point(int x, int y) { struct Point p = {x, y}; return p; // kopya döndürülür }

Ana risk — performanstır: bir yapının kopyası oluşturulur ve döndürülür. Ayrıca, yerel bir değişkenin adresini hatalı döndürme durumunda yapı, geçersiz bir bellek alanına işaret edebilir:

struct Point* bad() { struct Point p = {1, 2}; return &p; // hata: yerel bir değişkenin adresini döndürme }

Bilinçsizlikten Kaynaklanan Gerçek Hata Örnekleri


Hikaye

Küçük yığınlı yerleşik cihazlarda, geliştirici büyük bir yapıyı (1 KB) değeriyle iletti ve bu, yığın taşmasına ve sistemde kesintilere neden oldu. Soruşturma, her yapının kopyalanmasının derin çağrı yığınında yığın belleğinin tükenmesine yol açtığını gösterdi.


Hikaye

Kurumsal bir sunucu sisteminde, bir programcı yerel bir yapının göstericisini döndürdü ve fonksiyondan çıkıldığında "asılı" göstericilere erişim hatası meydana geldi. Bu, üretimde nadir bir şekilde yeniden üretilebilen kritik bir segment hatasıyla sonuçlandı.


Hikaye

Açık Kaynak projesinde, karmaşık yapılar içeren bir fonksiyondan döndürme işlemi sonrası performans keskin bir şekilde düştü. Profil oluşturucu, gereksiz birçok kez yapı kopyalamak için işlemci zamanının harcandığını tespit etti.