ProgramlamaGömülü Geliştirici

C dilinde dinamik veri yapılarını (örneğin bağlantılı listeler) ilan etme ve kullanma ayrıntılarından bahsedin. Uygulamalarında dikkat edilmesi gereken özel noktalar nelerdir?

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

Cevap.

Dinamik veri yapıları C dilinde (örneğin bağlantılı listeler, ağaçlar) genellikle işaretçiler ve dinamik bellek tahsisi kullanılarak elle gerçekleştirilir (malloc, calloc, free).

Uygulamadaki önemli noktalar:

  • İşaretçileri mutlaka başlatın: başlatılmamış işaretçilerdeki atık, bellek sızıntılarına veya segment hatalarına yol açar.
  • Bellek tahsis hatalarını işleyin: malloc/calloc sonucunu kontrol edin, aksi takdirde program geçersiz bir işaretçi ile çalışabilir.
  • Belleği doğru bir şekilde serbest bırakın: tahsis edilen her yapı için free çağırmayı unutmayın, böylece sızıntı birikimi olmaz.
  • Asılı işaretçilerden kaçının (free'den sonra işaretçiyi sıfırlayın).

Örnek: basit tek yönlü liste oluşturma ve silme

typedef struct Node { int value; struct Node* next; } Node; Node* create_node(int value) { Node* n = malloc(sizeof(Node)); if (!n) return NULL; n->value = value; n->next = NULL; return n; } void free_list(Node* head) { while (head) { Node* tmp = head; head = head->next; free(tmp); } }

Kandırmaca Sorusu.

Liste düğümlerinin belleğini döngü içinde yalnızca geçerli işaretçiyi kullanarak serbest bırakmak mümkün mü?

Sonraki işaretçiyi önceden kaydetmeden geçerli düğümü serbest bırakmak doğru değildir! free çağrısından sonra adresindeki bellek değiştirilebilir veya işletim sistemine dönebilir.

Doğru yaklaşım:

Node* curr = head; while (curr) { Node* next = curr->next; free(curr); curr = next; }

next'i kaydetmezseniz, zaten serbest bırakılmış (ve muhtemelen sizin olmayan!) bir belleğe erişim gerçekleşir.


Tarih


Bir işlemin hatalı sonlanması durumunda tüm listeyi (free) temizlemeyi unutarak 10000 ekleme/çıkarma işlemi üzerinden çalışan otomatik test sonucunda bellek tüketimi kademeli olarak arttı — profilleyici büyük bir sızıntı gösterdi.


Geliştirici, listenin son düğümüne işaret edici tutuyordu ancak tüm öğeler silindikten sonra bunu sıfırlamıyordu, bu nedenle başka bir işlevde zaten serbest bırakılmış belleği referans alarak zor yakalanan bir segfault aldı.


Ağaçlarla çalışırken, sadece kök düğümü serbest bırakarak tüm "alt ağaçları" rekürsif olarak silmeyi unuttular. Sonuç: tamamlanmamış temizleme nedeniyle bellek yapısı kirli kalmış, periyodik hatalara yol açmıştır.