Geschichte der Frage: Die Sprache C war schon immer flexibel in Bezug auf die Typumwandlung, um die Arbeit mit niedrigstufigem Speicher und verschiedenen Plattformen zu erleichtern. Ihre Kürze und Macht können jedoch leicht zu Schwachstellen und Fehlern führen, die mit falschen Typumwandlungen verbunden sind, insbesondere beim Arbeiten mit Zeigern und bitweiser Arithmetik.
Problem:
Lösung:
Beispielcode:
#include <stdio.h> void print_double_as_int(double d) { int i = (int)d; printf("Wert: %d\n", i); } void *ptr = malloc(16); int *ip = (int*)ptr; // Zugriff auf Rohspeicher: zulässig, wenn ptr tatsächlich auf int zeigt
Wesentliche Merkmale:
1. Wann ist es zulässig, void in einen Zeiger auf eine Struktur umzuwandeln, und ist das immer sicher?*
Diese Umwandlung ist sicher, wenn die Adresse tatsächlich auf eine Instanz dieser Struktur zeigt, andernfalls ist das Verhalten undefiniert (undefined behavior).
2. Was passiert, wenn Sie einen Zeiger auf eine Struktur einer Länge in einen Zeiger auf eine Struktur mit weniger oder mehr Feldern umwandeln?
Der Zugriff auf die Felder der "neuen" Struktur führt zum Lesen/Schreiben über die Grenzen der ursprünglichen Struktur hinweg, was möglicherweise Datenbeschädigungen zur Folge hat.
Beispielcode:
typedef struct {int a;} S1; typedef struct {int a; int b;} S2; S1 s; S2 *ps2 = (S2*)&s; // ps2->b — Zugriff auf "Müll"
3. Kann man sicher einen Zeiger auf int in einen Zeiger auf char umwandeln, um auf die Bytes dieser Zahl zuzugreifen?
Dies ist eine typische Technik zur Arbeit mit Speicher — der byteweise Zugriff ist zulässig, erfordert jedoch Vorsicht, da Probleme mit der Ausrichtung auftreten können und die Byte-Reihenfolge von der Architektur abhängt (big-endian/little-endian).
Ein Junior-Programmierer optimierte die Zugriffszeit, indem er einen Zeiger von einem Roh-Array in einen Zeiger auf eine Datenstruktur mit Feldern unterschiedlicher Typen umwandelte.
Vorteile:
Nachteile:
Nach der Überarbeitung wurde jedes Byte des Pakets manuell über memcpy extrahiert.
Vorteile:
Nachteile: