Was ist der Unterschied zwischen size_t und int in C ++?
Frage
In mehreren C ++ Beispiele sehe ich eine Verwendung des Typs size_t wo ich eine einfache int verwendet hätte. Was ist der Unterschied, und warum soll size_t besser sein?
Lösung
Die stdlib.h und stddef.h Header-Dateien definieren einen Datentyp namens size_t , die die Größe eines Objekts zu repräsentieren verwendet wird. Bibliotheksfunktionen, die Größen nehmen erwarten, dass sie vom Typ size_t sein, und der Operator sizeof ausgewertet size_t.
Die tatsächliche Art der size_t ist plattformabhängig; ein häufiger Fehler ist size_t ist die gleiche wie unsigned int zu übernehmen, die zu Programmierfehlern führen können, insbesondere als 64-Bit-Architekturen weiter verbreitet werden.
Überprüfen Sie auch Warum size_t Angelegenheiten
Andere Tipps
size_t ist die Art verwendet, Größen darstellen (wie der Name schon sagt). Seine Plattform (und sogar potenziell Implementierung) abhängig und sollte nur für diesen Zweck verwendet werden. Offensichtlich, was eine Größe ist size_t nicht signiert. Viele stdlib Funktionen, einschließlich malloc, sizeof und verschiedene String-Operation Funktionen verwenden size_t als Datentyp.
Ein int standardmäßig signiert ist, und obwohl seine Größe ist auch plattformabhängig, es wird eine feste 32bits auf modernsten Maschinen (und obwohl size_t 64 Bit auf 64-Bit-Architektur ist, bleiben int 32bits lange auf diesen Architekturen ).
Um es zusammenzufassen:. Verwendung size_t die Größe eines Objekts und int (oder lang) in anderen Fällen zu vertreten
Es ist, weil size_t etwas anderes als ein int sein kann (vielleicht eine Struktur). Die Idee ist, dass es es ist Aufgabe des zugrunde liegenden Typ abkoppelt.
Der size_t
Typ wird als unsigned integralen Typ des sizeof
Operator definiert. In der realen Welt wird man oft int
als 32 Bits definiert (für Rückwärtskompatibilität), aber size_t
als 64 Bits definiert (so können Sie erklären, Arrays und Strukturen mehr als 4 GiB groß) auf 64-Bit-Plattformen. Wenn ein long int
auch 64-Bit ist, ist dies die LP64-Konvention genannt; wenn long int
32 Bit ist aber long long int
und Zeiger sind 64 Bits, das ist LLP64. Sie könnten auch den umgekehrten bekommen, ein Programm, das 64-Bit-Befehle für die Geschwindigkeit verwendet, aber 32-Bit-Zeiger-Speicher zu speichern. Auch int
ist signiert und size_t
ist nicht signiert.
Es gab historisch eine Reihe von anderen Plattformen, auf denen Adressen breite oder kürzer als die native Größe int
waren. In der Tat, in den 70er und frühen 80er Jahren war dies häufiger als nicht: alle populären 8-Bit-Mikrocomputer hatte 8-Bit-Register und 16-Bit-Adressen und den Übergang zwischen 16 und 32 Bit erzeugt auch viele Maschinen, die hatte Adressen breiter als ihre Register. Ich gelegentlich noch Fragen sehe hier über Borland Turbo C für MS-DOS, deren Huge Memory-Modus hatten 20-Bit-Adressen in 32 Bit auf 16-Bit-CPU gespeichert (die aber konnte den 32-Bit-Befehlssatz der 80386 unterstützen); die Motorola 68000 hatte ein 16-Bit-ALU mit einem 32-Bit-Registern und Adressen; es gab IBM-Mainframes mit 15-Bit, 24-Bit oder 31-Bit-Adressen. Sie auch noch andere ALU und adress Busgrößen in Embedded-Systemen sehen.
Jedes Mal, int
kleiner als size_t
, und Sie versuchen, die Größe zu speichern oder in einem unsigned int
eine sehr großen Datei oder ein Objekt versetzt, besteht die Möglichkeit, dass es überlaufen könnte und einen Fehler verursachen. Mit einem int
, gibt es auch die Möglichkeit, eine negative Zahl zu bekommen. Wenn ein int
oder unsigned int
breite, wird das Programm ordnungsgemäß ausgeführt werden, sondern Abfall Speicher.
Sie sollten in der Regel verwenden Sie den richtigen Typ für den Zweck, wenn Sie Portabilität wollen. Eine Menge Leute wird empfohlen, anstelle von unsigned unterzeichnet Mathematik verwenden (böse, subtile Bugs wie 1U < -3
zu vermeiden). Zu diesem Zweck definiert die Standardbibliothek ptrdiff_t
in <stddef.h>
als signierte Typ des Ergebnisses eines Zeigers von dem anderen subtrahiert wird.
Das sei gesagt, eine Abhilfe könnte auf Grenzen überprüfen Sie alle Adressen und Offsets gegen INT_MAX
und entweder 0
oder INT_MIN
als angemessen, und schalten Sie den Compiler-Warnungen über unterzeichnet Vergleichens und unsigned Mengen, falls Sie eine verpassen. Sie sollten immer, immer, immer die Überprüfung Ihre Array für Überlauf in C greift sowieso.
Die Definition von SIZE_T
wird bei gefunden:
https://msdn.microsoft.com/en-us/library/cc441980. aspx und https://msdn.microsoft.com/en- us / library / cc230394.aspx
Einfügen hier die erforderlichen Informationen:
SIZE_T
ist ein ULONG_PTR
die maximale Anzahl von Bytes, auf die ein Zeiger darstellt zeigen kann.
Dieser Typ ist wie folgt deklariert:
typedef ULONG_PTR SIZE_T;
Ein ULONG_PTR
ist ein unsigned long-Typ für Zeiger-Präzision verwendet. Es wird verwendet, wenn ein Zeiger auf eine lange Art Casting Pointer-Arithmetik auszuführen.
Dieser Typ ist wie folgt deklariert:
typedef unsigned __int3264 ULONG_PTR;