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ı:
Değer ile geçirmenin dezavantajları:
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 }
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.