Sorunun Tarihi: C dili, düşük seviyeli bellek ve çeşitli platformlarla çalışmayı kolaylaştırmak için tür dönüşümleri konusunda her zaman esnek olmuştur. Ancak, kısalığı ve gücü, yanlış tür dönüşümüne bağlı zafiyetler ve hatalar doğurabilir, özellikle işaretçiler ve bit düzeyinde aritmetik ile çalışırken.
Problemler:
Çözüm:
Kod örneği:
#include <stdio.h> void print_double_as_int(double d) { int i = (int)d; printf("Değer: %d ", i); } void *ptr = malloc(16); int *ip = (int*)ptr; // Raw belleğe erişim: ptr gerçekten bir int'e işaret ediyorsa geçerlidir
Anahtar Özellikler:
1. void işaretçisini bir yapı işaretçisine dönüştürmek ne zaman güvenlidir, her zaman mı güvenlidir?*
Bu dönüşüm güvenlidir, eğer adres gerçekten o yapının bir örneğine işaret ediyorsa; aksi takdirde davranış belirsizdir.
2. Aynı uzunluktaki bir yapı işaretçisini, daha az veya daha fazla alan olan bir yapının işaretçisine dönüştürürsek ne olur?
"Yeni" yapının alanlarına erişim, en çok orijinal yapının sınırları dışındaki okumalar/yazmalarla sonuçlanabilir ve bu da veri bozulmasına neden olabilir.
Kod örneği:
typedef struct {int a;} S1; typedef struct {int a; int b;} S2; S1 s; S2 *ps2 = (S2*)&s; // ps2->b - "çöplüğe" erişim
3. Bir int işaretçisini char işaretçisine dönüşüm yaparak bu sayının baytlarına güvenli bir şekilde erişebilir miyiz?
Bu, bellekte çalışmanın tipik bir tekniğidir; baytlarla erişim geçerli olsa da, hizalama sorunları ve bayt sırasının mimari (big-endian/little-endian) ile değişebileceği için dikkatli olunması gerekir.
Genç bir programcı erişim süresini optimize etmek için bir ağ paketini işlemek üzere raw bir diziden farklı türde alanlara sahip veri yapılarına işaretçileri dönüştürerek işlemiştir.
Artılar:
Eksiler:
Daha sonra, her bayt paketten elle memcpy ile çıkarıldı.
Artılar:
Eksiler: