webentwicklung-frage-antwort-db.com.de

Variiert die Größe der Zeiger in C?

Mögliche Duplikate:
Kann die Größe der Zeiger variieren, auf was gezeigt wird?
Gibt es Plattformen, auf denen Zeiger auf verschiedene Typen unterschiedliche Größen haben?

Ist es möglich, dass sich die Größe eines Zeigers auf einen Float in c von einem Zeiger auf int unterscheidet? Nachdem ich es ausprobiert habe, erhalte ich dasselbe Ergebnis für alle Arten von Zeigern.

#include <stdio.h>
#include <stdlib.h>

int main()
{
    printf("sizeof(int*): %i\n", sizeof(int*));
    printf("sizeof(float*): %i\n", sizeof(float*));
    printf("sizeof(void*): %i\n", sizeof(void*));
    return 0;
}

Welche Ausgänge hier (OSX 10.6 64bit)

sizeof(int*): 8
sizeof(float*): 8
sizeof(void*): 8

Kann ich davon ausgehen, dass Zeiger verschiedener Typen dieselbe Größe haben (auf einem Bogen natürlich)?

27
Nils

Zeiger haben nicht immer die gleiche Größe auf demselben Bogen.

Sie können mehr über das Konzept von "nahen", "fernen" und "großen" Zeigern lesen, wie zum Beispiel ein Fall, in dem sich die Zeigergrößen unterscheiden ...

http://en.wikipedia.org/wiki/Intel_Memory_Model#Pointer_sizes

20
Johan Kotlinski

In alten Tagen, z. Borland C-Compiler auf der DOS-Plattform gab es insgesamt (glaube ich) 5 Speichermodelle, die sogar teilweise gemischt werden konnten. Im Wesentlichen hatten Sie die Wahl zwischen kleinen oder großen Zeigern auf Daten und kleinen oder großen Zeigern auf Code sowie einem "winzigen" Modell, bei dem Code und Daten einen gemeinsamen Adressraum von (wenn ich mich recht erinnere) 64 KB hatte.

Es war möglich, "große" Zeiger in einem Programm anzugeben, das ansonsten im "winzigen" Modell erstellt wurde. Im schlimmsten Fall es war also möglich, Zeiger unterschiedlicher Größe auf denselben Datentyp zu haben im selben Programm!

Ich denke, dass der Standard dies nicht einmal verbietet, theoretisch könnte ein obskurer C-Compiler dies auch heute noch tun. Es gibt jedoch zweifellos Experten, die dies bestätigen oder korrigieren können.

11
Carl Smotricz

Zeiger auf Daten müssen immer mit void* kompatibel sein, so dass sie heutzutage in der Regel als gleich breite Typen realisiert werden.

Diese Anweisung gilt nicht für Funktionszeiger, sie können unterschiedliche Breiten haben. Aus diesem Grund ist in C99 ein Casting-Funktionszeiger auf void* undefiniertes Verhalten. 

8
Jens Gustedt

Soweit ich es verstehe, gibt es im C-Standard nichts, was garantiert, dass Zeiger auf verschiedene Typen dieselbe Größe haben müssen. In der Theorie könnten also ein int * und ein float * auf derselben Plattform unterschiedliche Größen haben, ohne dass Regeln verletzt werden.

Es besteht die Anforderung, dass char * und void * die gleichen Repräsentations- und Ausrichtungsanforderungen haben, und es gibt verschiedene andere ähnliche Anforderungen für verschiedene Teilmengen von Zeigertypen, aber es gibt nichts, was alles umfasst.

In der Praxis ist es unwahrscheinlich, dass Sie auf eine Implementierung stoßen, die unterschiedlich große Zeiger verwendet, es sei denn, Sie befinden sich an ziemlich dunklen Orten. 

5
Nigel Harper

Ja, die Größe eines Zeigers ist plattformabhängig. Insbesondere hängt die Größe eines Zeigers von der Zielprozessorarchitektur und der "Bit-Ness" ab, für die Sie kompilieren.

Als Faustregel gilt, dass ein Zeiger auf einer 64-Bit-Maschine in der Regel 64 Bit und auf einer 32-Bit-Maschine normalerweise 32 Bit umfasst. Es gibt jedoch Ausnahmen.

Da ein Zeiger nur eine Speicheradresse ist, hat er immer dieselbe Größe, unabhängig davon, worauf der Speicher verweist, auf den er verweist. Ein Zeiger auf einen Float, ein Char oder ein Int haben also dieselbe Größe.

3

Ich wollte eine Antwort schreiben, dass C99 verschiedene Zeigerumwandlungsanforderungen hat, die mehr oder weniger sicherstellen, dass Zeiger auf Daten alle dieselbe Größe haben müssen. Beim sorgfältigen Lesen habe ich jedoch festgestellt, dass der C99 speziell dafür ausgelegt ist, Zeiger in unterschiedlichen Größen für verschiedene Typen zu haben. 

Bei einer Architektur, bei der die Ganzzahlen 4 Byte sind und 4 Byte ausgerichtet sein müssen, kann ein int-Zeiger zwei Bits kleiner sein als ein char- oder void-Zeiger. Vorausgesetzt, die Besetzung führt tatsächlich die Verschiebung in beide Richtungen durch, ist mit C99 alles in Ordnung. Es sagt hilfreich aus, dass das Ergebnis der Umwandlung eines Zeichenzeigers auf einen falsch ausgerichteten int-Zeiger undefiniert ist.

Siehe C99-Standard . Abschnitt 6.3.2.3

3
JeremyP

Ja. Dies ist ungewöhnlich, aber dies würde sicherlich auf Systemen passieren, die nicht byteadressierbar sind. Z.B. ein 16-Bit-System mit 64 Kword = 128 KB Speicher. Auf solchen Systemen können Sie immer noch 16-Bit-Int-Zeiger haben. Ein Zeichenzeiger auf ein 8-Bit-Zeichen würde jedoch ein zusätzliches Bit benötigen, um Hochbyte/Lowbyte innerhalb des Wortes anzuzeigen, und somit hätten Sie 17/32 Bit-Zeichenzeiger. 

Das hört sich vielleicht exotisch an, aber viele DSPs verbringen 99.x% der Zeit damit, speziellen numerischen Code auszuführen. Ein Sound-DSP kann etwas einfacher sein, wenn er nur 16-Bit-Daten verarbeiten muss, wobei die gelegentlichen 8-Bit-Berechnungen vom Compiler emuliert werden müssen.

3
MSalters

Kann ich davon ausgehen, dass Zeiger verschiedener Typen dieselbe Größe haben (auf einem Bogen natürlich)?

Für die Plattformen mit Flat-Memory-Modell (= alle gängigen/modernen Plattformen) wäre die Zeigergröße gleich.

Für die Plattformen mit segmentiertem Speichermodell gibt es aus Effizienzgründen oft plattformspezifische Zeigertypen unterschiedlicher Größe. (Zum Beispiel far-Zeiger im DOS, da die CPU 8086 ein segmentiertes Speichermodell verwendet.) Dies ist jedoch plattformspezifisch und nicht standardmässig.

Sie sollten wahrscheinlich berücksichtigen, dass sich die Größe des normalen Zeigers in C++ von der Größe des Zeigers zur virtuellen Methode unterscheiden kann. Zeiger auf virtuelle Methoden müssen zusätzliche Informationen erhalten, um nicht ordnungsgemäß mit dem Polymorphismus zu arbeiten. Dies ist wahrscheinlich nur die mir bekannte Ausnahme, die immer noch relevant ist (da ich bezweifle, dass das segmentierte Speichermodell es jemals wieder schaffen wird).

1
Dummy00001

Ein Zeiger ist eine Speicheradresse - und sollte daher auf einer bestimmten Maschine gleich sein. 32-Bit-Maschine => 4Bytes, 64 Bit => 8 Bytes.

Unabhängig vom Datentyp der Sache, auf die der Zeiger zeigt, wäre die Größe eines Zeigers auf einer bestimmten Maschine gleich (da der zum Speichern einer Speicheradresse erforderliche Speicherplatz derselbe ist)

Annahme: Ich spreche von Zeigern auf Datenwerte, die Sie in Ihrer Frage angegeben haben.

0
Gishu

Zeiger haben immer die gleiche Größe auf demselben Arch, unabhängig von dem Datentyp, auf den sie verweist . Andernfalls sind Dinge wie das Casting zwischen verschiedenen Zeigertypen unbrauchbar und brechen viele Dinge.

Viele gebräuchliche Codierungstechniken hängen von der Umwandlung zwischen beispielsweise einem leeren Zeiger (oder einem Zeichen) auf verschiedene Strukturen ab, abhängig von der Größe.

Nimm selbst das Standard-printf (), muss auf verschiedene Arten von Daten verweisen können. Wenn Zeiger eine andere Größe haben, kann die Implementierung von printf sehr unübersichtlich werden.

0
Prof. Falken

Es gibt Plattformen, auf denen Funktionszeiger eine andere Größe haben als andere Zeiger. 

Ich habe noch nie so viele Variationen gesehen. Alle anderen Zeiger müssen höchstens sizeof (void *) sein, da der Standard verlangt, dass sie ohne Informationsverlust in void * umgewandelt werden können.

0
blucz