Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
Vorwort
Vorwort des Gutachters
1 Einstieg in C
2 Das erste Programm
3 Grundlagen
4 Formatierte Ein-/Ausgabe mit »scanf()« und »printf()«
5 Basisdatentypen
6 Operatoren
7 Typumwandlung
8 Kontrollstrukturen
9 Funktionen
10 Präprozessor-Direktiven
11 Arrays
12 Zeiger (Pointer)
13 Kommandozeilenargumente
14 Dynamische Speicherverwaltung
15 Strukturen
16 Ein-/Ausgabe-Funktionen
17 Attribute von Dateien und das Arbeiten mit Verzeichnissen (nicht ANSI C)
18 Arbeiten mit variabel langen Argumentlisten – <stdarg.h>
19 Zeitroutinen
20 Weitere Headerdateien und ihre Funktionen (ANSI C)
21 Dynamische Datenstrukturen
22 Algorithmen
23 CGI mit C
24 MySQL und C
25 Netzwerkprogrammierung und Cross–Plattform-Entwicklung
26 Paralleles Rechnen
27 Sicheres Programmieren
28 Wie geht’s jetzt weiter?
A Operatoren
B Die C-Standard-Bibliothek
Stichwort

Download:
- ZIP, ca. 10,6 MB
Buch bestellen
Ihre Meinung?

Spacer
<< zurück
C von A bis Z von Jürgen Wolf
Das umfassende Handbuch
Buch: C von A bis Z

C von A bis Z
3., aktualisierte und erweiterte Auflage, geb., mit CD und Referenzkarte
1.190 S., 39,90 Euro
Galileo Computing
ISBN 978-3-8362-1411-7
Pfeil 15 Strukturen
Pfeil 15.1 Struktur deklarieren
Pfeil 15.2 Initialisierung und Zugriff auf Strukturen
Pfeil 15.3 Strukturen als Wertübergabe an eine Funktion
Pfeil 15.4 Strukturen als Rückgabewert einer Funktion
Pfeil 15.5 Strukturen vergleichen
Pfeil 15.6 Arrays von Strukturen
Pfeil 15.7 Strukturen in Strukturen (Nested Structures)
Pfeil 15.8 Kurze Zusammenfassung zu den Strukturen
Pfeil 15.9 Unions
Pfeil 15.10 Der Aufzählungstyp »enum«
Pfeil 15.11 Typendefinition mit »typedef«
Pfeil 15.12 Attribute von Strukturen verändern (nicht ANSI C)
Pfeil 15.13 Bitfelder
Pfeil 15.14 Das »offsetof«-Makro


Galileo Computing - Zum Seitenanfang

15.12 Attribute von Strukturen verändern (nicht ANSI C) topZur vorigen Überschrift

Der Speicherplatz für eine Struktur wird – wie schon bei den Arrays – lückenlos im Hauptspeicher abgelegt. Damit das System schneller auf diese Daten im Hauptspeicher zurückgreifen kann, werden diese in durch zwei oder in durch vier teilbare Adressen angeordnet. Dies hängt vom Betriebssystem ab. Dabei wird einiges an Speicherplatz verschwendet. Zur Demonstration dient das folgende Programm:

/* alignment1.c */
#include <stdio.h>
#include <stdlib.h>

struct speicher {
   char x;
   int z;
};

int main(void) {
   struct speicher test;

   printf("%u Bytes\n",sizeof(test));
   return EXIT_SUCCESS;
}

Auf 32-Bit-Systemen dürfte diese Struktur acht Byte benötigen. Und dies, obwohl es eigentlich fünf Byte sein sollten (char + int = 5 Byte).

Abbildung 15.10 Speicherabbild mit einer Struktur mit unbenannten Lücken

Abbildung 15.10 stellt ein Vier-Byte-Alignment dar, wie es bei den meisten Systemen der Fall sein wird. Dabei entsteht eine Lücke von drei Byte (grau gefärbt), die ungenutzt bleibt. Es wird hier auch vom Padding (Auffüllen, Polsterung) des Speichers gesprochen.


Hinweis

Dies ist übrigens auch der Grund, warum Sie Strukturen nicht direkt miteinander vergleichen können. Auch ein Low-Level-Vergleich, Byte für Byte, kann da nicht viel helfen, da dieser durch zufällig gesetzte Bits in den Löchern verfälscht sein könnte. In solch einem Fall müssen Sie sich mit einer eigenen Funktion behelfen, die die einzelnen Strukturelemente miteinander vergleicht.


Viele Compiler besitzen daher einen speziellen Schalter, mit dem diese Lücke entfernt werden kann. Wobei ich gleich anmerken muss, dass dies nicht ANSI-C-konform, sondern compiler-abhängig ist.

Mit dem Schalter

__attribut__

können dem Compiler mehrere Informationen zu einer Funktion, zu Variablen oder Datentypen übergeben werden. Um damit eine lückenlose Speicherbelegung zu erreichen, könnten Sie das Attribut packed verwenden.

Sollte dieser Schalter bei Ihrem Compiler nicht funktionieren, können Sie auch das Pragma pack verwenden:

#pragma pack(n)

Für n kann hier der Wert 1, 2, 4, 8 oder 16 angegeben werden. Je nachdem, welche Angabe Sie dabei machen, wird jedes Strukturelement nach dem ersten kleineren Elementtyp oder auf n Byte abgespeichert.

Beim Testen auf verschiedenen Systemen und unterschiedlichen Compilern gab es keine Probleme mit dem #pragma pack. Die Option __attribut__ hingegen wurde nicht von jedem Compiler erkannt. Wie Sie dabei vorgehen, müssen Sie letztendlich selbst herausfinden.

Hier folgt das Beispiel dazu:

/* alignment2.c */
#include <stdio.h>
#include <stdlib.h>

/* Lässt sich dieses Listing nicht übersetzen,
 * entfernen Sie __attribute__((packed)) und
 * verwenden stattdessen #pragma pack(1).
 */

/* #pragma pack(1) */
struct speicher {
   char x;
   int z;
} __attribute__ ((packed));

int main(void) {
   struct speicher test;

   printf("%u Bytes\n",sizeof(test));
   return EXIT_SUCCESS;
}

Damit benötigt die Struktur tatsächlich 5 Byte. Dies funktioniert bei manchen Compilern auch bei den enum-Aufzählungen:

/* alignment3.c */
#include <stdio.h>
#include <stdlib.h>

/* #pragma pack(1); */
enum{TRUE,FALSE}__attribute__ ((packed));

int main(void) {
   printf("%u Bytes\n",sizeof(TRUE));
   return EXIT_SUCCESS;
}

Das Beispiel funktionierte beim Testen allerdings nur mit dem gcc-Compiler. In diesem Fall wird durch packed ein 1-Byte-Alignment angelegt. Das ist gegenüber den vier Bytes ohne packed beachtlich. Diese Werte können natürlich von System zu System unterschiedlich sein.


Hinweis

Natürlich müssen Sie sich auch darüber im Klaren sein, dass hier zwischen Performance und Speicherplatz gewählt wird. Schließlich greifen Sie ja in die geschwindigkeitsoptimierte Speicherung des Betriebssystems ein.


Bei den Vorteilen, die mit packed oder dem Pragma pack erzielt werden, sollten Sie auch die Nachteile beachten. Wenn diese Daten (struct speicher) auf einem System mit fünf Bytes pro Struktur in einer Datei gespeichert werden, kann es passieren, dass diese Daten auf einem anderen System falsch angezeigt werden, weil das System vielleicht dort die Option packed nicht kennt und einfach ignoriert. Außerdem könnten Low-Level-Funktionen fehlschlagen, da sich die Daten wegen des Alignments nicht dort befinden, wo die Funktionen diese vermutet.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.






<< zurück
  
  Zum Katalog
Zum Katalog: C von A bis Z

 C von A bis Z
Jetzt bestellen


 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Einstieg in C++






 Einstieg in C++


Zum Katalog: C++ von A bis Z






 C++ von A bis Z


Zum Katalog: C/C++






 C/C++


Zum Katalog: Shell-Programmierung






 Shell-Programmierung


Zum Katalog: Linux-UNIX-Programmierung






 Linux-UNIX-
 Programmierung


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für
 Fachinformatiker


Zum Katalog: Ubuntu GNU/Linux






 Ubuntu GNU/Linux


Zum Katalog: Coding for Fun







 Coding for Fun 


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo




Copyright © Galileo Press 2009
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de