Variiert die Größe der Zeiger in C? [duplicate]

Lesezeit: 7 Minuten

Benutzer-Avatar
Nils

Mögliche Duplikate:

Kann die Größe von Zeigern variieren, je nachdem, worauf 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 ein Float in c von einem Zeiger auf int unterscheidet? Nach dem Ausprobieren erhalte ich für alle Arten von Zeigern das gleiche Ergebnis.

#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 Ausgaben hier (OSX 10.6 64bit)

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

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

  • betrogen? stackoverflow.com/questions/1473935/…

    – Johann Kotlinski

    19. August 2010 um 8:54 Uhr

  • @kotlinski: Es gibt zwei boolesche Fragen: die Titelfrage (unterscheiden sie sich?) und die letzte (sind sie gleich?). Welche antwortest du?

    – MSalter

    19. August 2010 um 8:57 Uhr

  • @MSalters: Hoppla! die letzten … sie dürfen variieren.

    – Johann Kotlinski

    19. August 2010 um 8:58 Uhr

  • 1473935 ist selbst ein Dupe von stackoverflow.com/questions/916051/…

    – Gilles ‘SO- hör auf, böse zu sein’

    19. August 2010 um 9:22 Uhr

  • Abgesehen von near und fardie der Programmierer beim Deklarieren eines Zeigers zuschreibt und hier nicht wirklich zutrifft, hatte der alte Crays char* größer als andere Zeiger, da das native Speicherschema keine Bytes adressierte.

    – Kartoffelklatsche

    19. August 2010 um 9:23 Uhr

Benutzer-Avatar
Johann Kotlinski

Pointer haben nicht immer die gleiche Größe auf dem gleichen Bogen.

Sie können mehr über das Konzept von “nahen”, “fernen” und “großen” Zeigern lesen, nur als Beispiel für einen Fall, in dem Zeigergrößen unterschiedlich sind …

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

  • Man könnte argumentieren, dass das, was Sie beschreiben, nicht “C” ist. Aber da DOS einst die Welt beherrschte und der De-facto-Standard war, habe ich Ihnen eine Stimme gegeben.

    – Prof. Falken

    19. August 2010 um 8:54 Uhr

  • Ja, aber auch in diesem Fall hat der Typ keinen Einfluss auf die Größe?

    – Nils

    19. August 2010 um 8:56 Uhr

  • Sie kann unterschiedlich sein, da unterschiedliche Typen in unterschiedlichen Speichersegmenten platziert werden können.

    – Johann Kotlinski

    19. August 2010 um 8:59 Uhr

  • @Amigable – Meinten Sie “amicable”? Aber netter Nick.

    – Agnel Kurian

    19. August 2010 um 10:18 Uhr

  • @Vulcan, nicht da ist ein “Amiga” im Namen. Und Clark Gable, Clark Kent (fast) und vielleicht noch einer. 🙂

    – Prof. Falken

    20. August 2010 um 9:27 Uhr

Früher gab es mit zB Borland C-Compilern auf der DOS-Plattform insgesamt (glaube ich) 5 Speichermodelle, die teilweise sogar 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 und einem “winzigen” Modell, bei dem Code und Daten einen gemeinsamen Adressraum von (wenn ich mich richtig erinnere) 64 KB hatten.

Es war möglich, “riesige” Zeiger innerhalb eines Programms zu spezifizieren, das ansonsten im “winzigen” Modell gebaut wurde. Also im schlimmsten Fall es war möglich, unterschiedlich große Zeiger auf denselben Datentyp zu haben im selben Programm!

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

  • Der Standard verbot es nicht direkt, aber die besonderen Details waren nicht standardisiert. Sie weisen jedoch zu Recht darauf hin, dass Sie unabhängig voneinander zwischen kleinen und großen Zeigern für Code und Daten wählen könnten.

    – MSalter

    19. August 2010 um 9:02 Uhr

Zeiger auf Daten müssen immer mit kompatibel sein void* so würden sie heute in der Regel als Typen gleicher Breite realisiert.

Diese Aussage gilt nicht für Funktionszeiger, sie können unterschiedliche Breiten haben. Aus diesem Grund werden in C99 Funktionszeiger auf gecastet void* ist undefiniertes Verhalten.

  • Das bedeutet nur das void * muss mindestens so groß sein wie der größte andere Zeigertyp.

    – Café

    19. August 2010 um 12:32 Uhr

  • @caf: Sie meinen wahrscheinlich “anderer Zeiger auf Datentyp” und “Breite” anstelle von “Größe”. Ja, ich denke, das habe ich in meinem ersten Absatz gesagt. Das zwingt andere Zeigerdatentypen nicht dazu, die gleiche Breite zu haben, aber es macht es sehr wahrscheinlich, da von zurückgeworfen wird void* muss noch alle Informationen haben, um das Objekt anzusprechen. Aber Sie haben Recht, eine hypothetische Architektur könnte das niederwertige Byte von Zeigern für alle Datentypen speichern, die an 256-Byte-Grenzen ausgerichtet sind 😉

    – Jens Gustedt

    19. August 2010 um 13:46 Uhr

  • Genau – Konvertieren von void * zu double * kann verlustbehaftet sein, aber nicht umgekehrt.

    – Café

    19. August 2010 um 23:53 Uhr

  • Kann jemand erklären, was “Breite” ist (im Gegensatz zu “Größe”)?

    – Thomas Eding

    2. Juli 2011 um 0:01 Uhr

  • @trinithis, Kommentare zu einjährigen Fragen sind kein guter Ort, um Fragen zu stellen. Die Breite ist die Anzahl der Bits, die effektiv für einen Typ verwendet werden. zB ein _Bool hat sizeof von mindestens eins, belegt also mindestens 8 Bit. Aber normalerweise verwendet es nur 1 Bit davon, also wäre seine Breite nur 1 statt 8. Die anderen Bits sind dann sogenannte Füllbits.

    – Jens Gustedt

    2. Juli 2011 um 5:50 Uhr

So wie ich es verstehe, gibt es im C-Standard nichts, was garantiert, dass Zeiger auf verschiedene Typen die gleiche Größe haben müssen, also könnten theoretisch ein int * und ein float * auf derselben Plattform unterschiedliche Größen haben, ohne gegen Regeln zu verstoßen.

Es gibt eine Anforderung, dass char * und void * die gleichen Darstellungs- 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 Zeiger unterschiedlicher Größe verwendet, es sei denn, Sie begeben sich an ziemlich obskure Orte.

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

Das mag exotisch klingen, aber viele DSPs verbringen 99,x % der Zeit damit, spezialisierten numerischen Code auszuführen. Ein Sound-DSP kann etwas einfacher sein, wenn er nur mit 16-Bit-Daten umgehen muss und die gelegentliche 8-Bit-Mathematik vom Compiler emuliert werden muss.

Ich wollte eine Antwort schreiben, die besagt, dass C99 verschiedene Anforderungen an die Zeigerkonvertierung hat, die mehr oder weniger sicherstellen, dass Zeiger auf Daten alle dieselbe Größe haben müssen. Als ich sie jedoch sorgfältig las, stellte ich fest, dass C99 speziell dafür entwickelt wurde, dass Zeiger für verschiedene Typen unterschiedliche Größen haben können.

Beispielsweise könnte auf einer Architektur, bei der die ganzen Zahlen 4 Bytes groß sind und auf 4 Bytes ausgerichtet sein müssen, ein int-Zeiger zwei Bit kleiner sein als ein char- oder void-Zeiger. Vorausgesetzt, die Besetzung führt die Verschiebung tatsächlich in beide Richtungen durch, ist C99 für Sie in Ordnung. Es sagt hilfreich aus, dass das Ergebnis der Umwandlung eines char-Zeigers in einen falsch ausgerichteten int-Zeiger undefiniert ist.

Siehe die C99-Standard. Abschnitt 6.3.2.3

Ja, die Größe eines Zeigers ist plattformabhängig. Genauer gesagt hängt die Größe eines Zeigers von der Zielprozessorarchitektur und der “Bit-Anzahl” ab, für die Sie kompilieren.

Als Faustregel gilt, dass ein Zeiger auf einem 64-Bit-Rechner normalerweise 64 Bit groß ist, auf einem 32-Bit-Rechner normalerweise 32 Bit. Es gibt jedoch Ausnahmen.

Da ein Zeiger nur eine Speicheradresse ist, hat er immer die gleiche Größe, unabhängig davon, was der Speicher enthält, auf den er zeigt. Ein Zeiger auf ein Float, ein Char oder ein Int haben also alle die gleiche Größe.

  • Ähm, das war nicht die Frage, die Frage war, ob Zeiger auf verschiedene Typen (float*, int*, void*) unterschiedliche Größen haben können (auf derselben Plattform), was nicht der Fall ist.

    – Nils

    19. August 2010 um 8:52 Uhr

  • +1 Ja, in alten 16-Bit-Fenstern gab es je nach Speichermodell und Verwendung einen nahen (16 Bit) und einen fernen Zeiger (32 Bit).

    – Stapler

    19. August 2010 um 8:52 Uhr

1386020cookie-checkVariiert die Größe der Zeiger in C? [duplicate]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy