it-swarm.com.de

Ist die sizeof (irgendein Zeiger) immer gleich vier?

Zum Beispiel: sizeof(char*) gibt 4 zurück. Wie int*, long long*, alles was ich ausprobiert habe. Gibt es Ausnahmen dazu?

214
Joel

Die Garantie, die Sie erhalten, ist das sizeof(char) == 1. Es gibt keine weiteren Garantien, einschließlich der Garantie, dass sizeof(int *) == sizeof(double *).

In der Praxis haben Zeiger auf einem 16-Bit-System die Größe 2 (sofern vorhanden), auf einem 32-Bit-System die Größe 4 und auf einem 64-Bit-System die Größe 8 Größe.

180
David Thornley

Selbst auf einer normalen x86-32-Bit-Plattform können Sie eine Vielzahl von Zeigergrößen erhalten. Probieren Sie dies anhand eines Beispiels aus:

struct A {};

struct B : virtual public A {};

struct C {};

struct D : public A, public C {};

int main()
{
    cout << "A:" << sizeof(void (A::*)()) << endl;
    cout << "B:" << sizeof(void (B::*)()) << endl;
    cout << "D:" << sizeof(void (D::*)()) << endl;
}

Unter Visual C++ 2008 erhalte ich 4, 12 und 8 für die Größe der Zeiger-auf-Member-Funktion.

Raymond Chen sprach darüber hier .

36
Eclipse

Nur eine weitere Ausnahme von der bereits geposteten Liste. Auf 32-Bit-Plattformen können Zeiger 6, nicht 4, Bytes aufnehmen:

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

int main() {
    char far* ptr; // note that this is a far pointer
    printf( "%d\n", sizeof( ptr));
    return EXIT_SUCCESS;
}

Wenn Sie dieses Programm mit Open Watcom kompilieren und ausführen, erhalten Sie 6, da die unterstützten fernen Zeiger aus 32-Bit-Offset- und 16-Bit-Segmentwerten bestehen

29
dmityugov

wenn Sie für eine 64-Bit-Maschine kompilieren, kann es 8 sein.

24
FryGuy

Technisch gesehen garantiert der C-Standard nur, dass sizeof (char) == 1 ist, und der Rest hängt von der Implementierung ab. Auf modernen x86-Architekturen (z. B. Intel/AMD-Chips) ist dies jedoch ziemlich vorhersehbar.

Sie haben wahrscheinlich gehört, dass Prozessoren als 16-Bit-, 32-Bit-, 64-Bit-Prozessoren usw. beschrieben wurden. Dies bedeutet normalerweise, dass der Prozessor N-Bits für Ganzzahlen verwendet. Da Zeiger Speicheradressen speichern und es sich bei den Speicheradressen um Ganzzahlen handelt, erfahren Sie auf diese Weise, wie viele Bits für Zeiger verwendet werden sollen. sizeof wird normalerweise in Bytes gemessen, sodass Code, der für 32-Bit-Prozessoren kompiliert wurde, eine Zeigergröße von 4 (32 Bit/8 Bit pro Byte) und Code für 64-Bit-Prozessoren eine Zeigergröße von 8 angibt (64 Bit/8 Bit pro Byte). Hieraus ergibt sich die Beschränkung von 4 GB RAM für 32-Bit-Prozessoren. Wenn jede Speicheradresse einem Byte entspricht, benötigen Sie für die Adressierung von mehr Speicher ganze Zahlen, die größer als 32 Bit sind.

17
Joseph Garvin

Zusätzlich zu den 16/32/64-Bit-Unterschieden können noch seltsamere Dinge auftreten.

Es gab Maschinen, bei denen sizeof (int *) ein Wert ist, wahrscheinlich 4, aber bei denen sizeof (char *) größer ist. Maschinen, die auf natürliche Weise Wörter anstelle von Bytes adressieren, müssen die Zeichenzeiger "erweitern", um anzugeben, welchen Teil des Wortes Sie wirklich benötigen, um den C/C++ - Standard ordnungsgemäß zu implementieren.

Dies ist jetzt sehr ungewöhnlich, da Hardwareentwickler den Wert der Adressierbarkeit von Bytes gelernt haben.

6
Darron

Die Größe des Zeigers hängt im Wesentlichen von der Architektur des Systems ab, in dem er implementiert ist. Zum Beispiel beträgt die Größe eines Zeigers in 32 Bit 4 Bytes (32 Bit) und 8 Bytes (64 Bit) in 64-Bit-Maschinen. Die Bittypen in einer Maschine sind nichts anderes als Speicheradressen, die sie haben können. 32-Bit-Maschinen können 2^32 Adressraum und 64-Bit-Maschinen können bis zu 2^64 Adressräume. Ein Zeiger (Variable, die auf einen Speicherort zeigt) sollte also auf eine beliebige Speicheradresse (2^32 for 32 bit and 2^64 for 64 bit) dass eine Maschine hält.

Aus diesem Grund wird die Größe eines Zeigers in einer 32-Bit-Maschine mit 4 Byte und in einer 64-Bit-Maschine mit 8 Byte angegeben.

6
Rndp13

8-Bit- und 16-Bit-Zeiger werden in den meisten Mikrocontrollern mit niedrigem Profil verwendet. Das heißt, jede Waschmaschine, jedes Mikro, jeder Kühlschrank, jeder ältere Fernseher und sogar jedes Auto.

Man könnte sagen, dass dies nichts mit der Programmierung in der realen Welt zu tun hat. Aber hier ist ein reales Beispiel: Arduino mit 1-2-4k RAM (abhängig vom Chip) mit 2 Byte Zeigern.

Es ist neu, billig, für jedermann zugänglich und es lohnt sich, es zu programmieren.

5
Kobor42

Zusätzlich zu dem, was die Leute über 64-Bit-Systeme (oder was auch immer) gesagt haben, gibt es andere Arten von Zeigern als Zeiger auf Objekte.

Ein Zeiger auf ein Element kann nahezu beliebig groß sein, je nachdem, wie sie von Ihrem Compiler implementiert wurden: Sie sind nicht unbedingt alle gleich groß. Versuchen Sie es mit einem Zeiger auf ein Mitglied einer POD-Klasse und einem Zeiger auf ein Mitglied, der von einer der Basisklassen einer Klasse mit mehreren Basen geerbt wurde. Was für ein Spaß.

4
Steve Jessop

Soweit ich mich erinnere, basiert es auf der Größe einer Speicheradresse. Auf einem System mit einem 32-Bit-Adressschema gibt sizeof 4 zurück, da dies 4 Bytes sind.

3
Will Mc

Im Allgemeinen ändert sich sizeof (so ziemlich alles), wenn Sie auf verschiedenen Plattformen kompilieren. Auf einer 32-Bit-Plattform haben Zeiger immer die gleiche Größe. Auf anderen Plattformen (64-Bit ist das offensichtliche Beispiel) kann sich dies ändern.

3
Sean Reilly

Nein, die Größe eines Zeigers kann je nach Architektur variieren. Es gibt zahlreiche Ausnahmen.

3
Judge Maygarden

Die Größe des Zeigers und von int beträgt 2 Byte im Turbo C-Compiler auf Windows 32-Bit-Computern.

Die Größe des Zeigers ist also compilerspezifisch. Im Allgemeinen sind die meisten Compiler jedoch so implementiert, dass sie 4-Byte-Zeigervariablen in 32-Bit- und 8-Byte-Zeigervariablen in 64-Bit-Maschinen unterstützen.

Die Größe des Zeigers ist also nicht bei allen Maschinen gleich.

3

In Win64 (Cygwin GCC 5.4) sehen wir uns das folgende Beispiel an:

Testen Sie zunächst die folgende Struktur:

struct list_node{
    int a;
    list_node* prev;
    list_node* next;
};

struct test_struc{
    char a, b;
};

Der Testcode ist unten:

std::cout<<"sizeof(int):            "<<sizeof(int)<<std::endl;
std::cout<<"sizeof(int*):           "<<sizeof(int*)<<std::endl;
std::cout<<std::endl;

std::cout<<"sizeof(double):         "<<sizeof(double)<<std::endl;
std::cout<<"sizeof(double*):        "<<sizeof(double*)<<std::endl;
std::cout<<std::endl;

std::cout<<"sizeof(list_node):      "<<sizeof(list_node)<<std::endl;
std::cout<<"sizeof(list_node*):     "<<sizeof(list_node*)<<std::endl;
std::cout<<std::endl;

std::cout<<"sizeof(test_struc):     "<<sizeof(test_struc)<<std::endl;
std::cout<<"sizeof(test_struc*):    "<<sizeof(test_struc*)<<std::endl;    

Die Ausgabe ist unten:

sizeof(int):            4
sizeof(int*):           8

sizeof(double):         8
sizeof(double*):        8

sizeof(list_node):      24
sizeof(list_node*):     8

sizeof(test_struc):     2
sizeof(test_struc*):    8

Sie können sehen, dass in 64-Bit sizeof(pointer)8 Ist.

2
Jayhello

Der Grund für die Größe Ihres Zeigers von 4 Byte ist, dass Sie für eine 32-Bit-Architektur kompilieren. Wie FryGuy betonte, würden Sie auf einer 64-Bit-Architektur 8 sehen.

1
Will Bickford

Ein Zeiger ist nur ein Container für eine Adresse. Auf einem 32-Bit-Computer beträgt Ihr Adressbereich 32 Bit, sodass ein Zeiger immer 4 Byte lang ist. Wenn Sie auf einem 64-Bit-Computer einen Adressbereich von 64 Bit haben, beträgt der Zeiger 8 Byte.

1
Ed S.

Aus Gründen der Vollständigkeit und des historischen Interesses gab es in der 64-Bit-Welt unterschiedliche Plattformkonventionen für die Größen von Long- und Long-Long-Typen mit den Bezeichnungen LLP64 und LP64, hauptsächlich zwischen Unix-Systemen und Windows. Ein alter Standard namens ILP64 hat auch int = 64-bit wide gemacht.

Microsoft hat LLP64 beibehalten, wobei Longlong = 64 Bit breit ist, aber lange bei 32 bleibt, um die Portierung zu vereinfachen.

Type           ILP64   LP64   LLP64
char              8      8       8
short            16     16      16
int              64     32      32
long             64     64      32
long long        64     64      64
pointer          64     64      64

Quelle: https://stackoverflow.com/a/384672/48026

0
Hernán