Muss beim Manipulieren des Speichers mit sizeof( char ) multipliziert werden?

Lesezeit: 6 Minuten

Benutzer-Avatar
scharfer Zahn

Kann ich mich bei der Verwendung von malloc und einer ähnlichen Speichermanipulation darauf verlassen, dass sizeof( char ) immer 1 ist?

Zum Beispiel muss ich Speicher für N Elemente des Typs zuweisen char. Multipliziert mit sizeof( char ) notwendig:

char* buffer = malloc( N * sizeof( char ) );

oder kann ich mich darauf verlassen, dass sizeof( char ) immer 1 ist und einfach die Multiplikation überspringen

char* buffer = malloc( N );

Ich verstehe das vollkommen sizeof wird während der Kompilierung ausgewertet und dann kann der Compiler sogar die Multiplikation kompilieren, sodass die Leistungseinbuße minimal und höchstwahrscheinlich null ist.

Ich frage hauptsächlich nach Code-Klarheit und Portabilität. Ist diese Multiplikation überhaupt notwendig zum char Typ?

Benutzer-Avatar
David Cournapeau

Per Definition ist sizeof(char) immer gleich 1. Ein Byte ist die Größe eines Zeichens in C, unabhängig von der Anzahl der Bits in einem Byte (8 auf einer gewöhnlichen Desktop-CPU).

Das typische Beispiel, bei dem ein Byte nicht 8 Bit ist, ist das PDP-10 und andere alte Mini-Computer-ähnliche Architekturen mit 9/36-Bit-Bytes. Aber Bytes, die nicht 2 ^ N sind, werden meiner Meinung nach extrem selten

Ich denke auch, dass dies der bessere Stil ist:

char* buf1;
double* buf2;

buf1 = malloc(sizeof(*buf1) * N);
buf2 = malloc(sizeof(*buf2) * N);

weil es funktioniert, egal welcher Zeigertyp ist.

  • Ich dachte, dass die Definition von 1Byte = 8 Bit ist. Haben Sie ein Beispiel, wo dies nicht zutrifft?

    – AlexDrenea

    18. Juni 2009 um 10:01 Uhr

  • Die Definition von 1 Byte sind N Bits, wobei N maschinenabhängig ist. Nicht alle Maschinen haben 8 Bit/Byte (obwohl es heutzutage nicht mehr so ​​viele gibt, die dies nicht tun)

    – 1800 INFORMATIONEN

    18. Juni 2009 um 10:04 Uhr

  • @AlexDrenea: Heute begegnen Sie normalerweise nur 8-Bit-Bytes. Aber die Definition eines Bytes variiert und ist nicht an heutige Architekturen gebunden, denn es gab Systeme mit 9-Bit-Bytes und sogar 36-Bit-Bytes. Wenn Sie sichergehen wollen, verwenden Sie statt Byte den ISO-Begriff „Oktett“.

    – OregonGhost

    18. Juni 2009 um 10:05 Uhr

Benutzer-Avatar
Aamir

sizeof(char) ist immer 1, egal welche Art von Speichermanipulation Sie durchführen.

Jedoch, sizeof(TCHAR) kann je nach Compiler-Optionen variieren.

  • Ich bin kein Experte, aber wird die Größe eines Zeichens in Unicode-Situationen nicht größer?

    – Alex S

    19. Juni 2009 um 8:37 Uhr

  • @Schatten, nein. In diesem Fall wird in der Regel der Breitzeichentyp wchar_t anstelle von char verwendet. Das Microsoft-spezifische TCHAR-Geschäft ist eine Möglichkeit, Code zu schreiben, der für breite oder schmale Zeichen kompiliert werden kann. Es ist nicht klar, ob das eine gute Idee war oder nicht.

    – RBerteig

    19. Juni 2009 um 8:48 Uhr

  • @RBerteig: Ich würde sagen, es ist klar, dass es eine schlechte Idee ist. Der einzige Grund, Non-Wide zu verwenden char strings unter Windows dient dazu, portablen Code zu haben, der auf anderen standardkonformeren Systemen (POSIX) genauso funktioniert. Sobald Sie schreiben TCHAR, ist Ihr Code bereits mit Windows-spezifischem Zeug verunreinigt und Sie können genauso gut direkt ihre breiten Funktionen und Typen verwenden. Es ist niemandem ähnlich will ihre Programme brechen ab, sobald der Benutzer versucht, einen Dateinamen mit Nicht-Codepage-Zeichen darin zu öffnen.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    11. Januar 2011 um 17:26 Uhr


  • @R., eigentlich TCHAR war wirklich ein Portabilitätsknüppel, um Windows 3.x-Programmierern von 8-Bit abzugewöhnen char indem sorgfältig konstruierter Code ohne Änderungen für Win16, Win32 in ASCII und Win32 in Unicode kompiliert werden kann. Seine Verwendung im Zusammenhang mit vielen Windows-API-Aufrufen wird Ihre Portabilität nicht beeinträchtigen. Nicht Verwenden Sie es jedoch für den Kern der Verarbeitung Ihrer Anwendung, oder Sie beeinträchtigen wirklich die Portabilität. Wenn Sie vermeiden TCHAR mit der API, bestätigen Sie dies bitte zur Kompilierzeit UNICODE definiert ist und vielleicht schreiben MessageBoxW nicht MessageBoxetc.

    – RBerteig

    11. Januar 2011 um 18:33 Uhr


Benutzer-Avatar
entspannen

Ich halte es für eine Art Anti-Muster. Es signalisiert, dass der Programmierer nicht genau wusste, was er tat, was den Rest des Codes sofort in ein zweifelhaftes Licht wirft.

Zugegeben, es ist nicht (mit Wikipedia) “ineffektiv”, aber ich finde es “weit entfernt von optimal”. Es kostet zur Laufzeit nichts, aber es verstopft den Code mit unnötigem Müll und signalisiert gleichzeitig, dass jemand es für notwendig hielt.

Beachten Sie außerdem, dass der Ausdruck nicht als Funktionsaufruf analysiert wird: sizeof ist keine Funktion. Sie rufen keine Funktion auf, indem Sie ihr das magische Symbol übergeben char. Sie wenden den integrierten unären Präfixoperator an sizeof in einen Ausdruck, und Ihr Ausdruck ist in diesem Fall eine Umwandlung in den Typ charwas in C geschrieben wird als (char).

Die Verwendung ist durchaus möglich und wird nach Möglichkeit dringend empfohlen sizeof bei anderen Ausdrücken ergibt es dann die Größe des Ausdruckswerts:

char a;
printf("A char's size is %u\n", (unsigned int) sizeof a);

Dies wird gedruckt 1immer, auf allen konformen C-Implementierungen.

Ich stimme David Cournapeau auch sehr zu und überlege, den Typ zu wiederholen Name in einem malloc()-Aufruf Auch eine Art Anti-Pattern sein.

Anstatt von

char *str;

str = malloc(N * sizeof (char));

dass viele schreiben würden, um einen Zeichenfolgenpuffer mit einer Kapazität von N Zeichen zuzuweisen, würde ich mitmachen

char *str;

str = malloc(N * sizeof *str);

Oder (nur für Strings) weglassen sizeof wie oben, aber das ist natürlich allgemeiner und funktioniert genauso gut für jede Art von Zeiger.

  • Ich stimme dir nicht zu. Wenn Sie es weglassen, müssen Sie (und jeder, der Ihren Code liest) daran denken, dass dies ein Sonderfall ist, und ihn als solchen erkennen. Das erhöht die kognitive Belastung. Manchmal ist mehr Code besser.

    – Michael Carmann

    18. Juni 2009 um 13:48 Uhr

  • Ja, sizeof ist keine Funktion – aber für mich liest es sich einfacher, wenn Sie es wie eine behandeln. Es sei denn, Sie kennen einen Fall, in dem die zusätzlichen Klammern die Ausgabe ändern?

    – Markieren Sie Lösegeld

    18. Juni 2009 um 16:02 Uhr

  • @Michael Carman – Normalerweise ist ein Sonderfall, da Sie häufig Zeichenfolgen zuweisen und mit ihnen arbeiten, während ein Array von Ints für jeden Zweck verwendet werden kann. Wir müssen Strings anders behandeln als willkürlich typisierte Arrays, und ich finde das Fehlen von sizeof(type) in einem malloc() eine schöne Erinnerung daran sein.

    – Chris Lutz

    6. Oktober 2009 um 2:46 Uhr

Obwohl es nicht notwendig ist, halte ich es für eine gute Praxis, sizeof( char ) beizubehalten, da dies den Code lesbarer macht und die Verwendung einer magischen Zahl vermeidet. Wenn der Code später geändert werden muss, sodass anstelle eines Zeichens die Größe von etwas in einen Zeiger für dieses Objekt übertragen wird, ist es einfacher, den Code zu ändern, als wenn Sie nur eine „1“ haben.

Benutzer-Avatar
Matthäus Murdoch

Es ist nicht erforderlich. Sehen hier (zum Beispiel).

sizeof(char) wird durch den C-Standard als immer definiert 1 (Byte). Beachten Sie das, weil sizeof gibt eine Reihe von zurück Bytes die Anzahl der Bits pro Byte ist irrelevant (und in der Praxis sowieso 8).

Benutzer-Avatar
Clemahieu

Etwas anderes, das Sie beachten sollten, ist, dass der Compiler statisch weiß, dass der Wert von sizeof (char) 1 ist, und dass er auch weiß, dass die Multiplikation einer Zahl mit einer statischen 1 impliziert, dass die Multiplikation nicht durchgeführt werden muss; der Compiler wird es optimieren. Leistungsbedenken sollten aus diesen Gründen nicht berücksichtigt werden.

Benutzer-Avatar
osgx

Aus “Neuer C-Standard. Ein wirtschaftlicher und kultureller Kommentar”.

  1. Statistik: 2,0% von sizeof werden entnommen char und 1,5% – von unsigned char. Seite 1033 in Version 1.2 des Buches.
  2. Seite 1037.

Die Anzahl der Bits in der Darstellung eines Zeichentyps ist unerheblich. Per Definition ist die Anzahl der Bytes in einem Byte eines Zeichentyps eins.

Codierungsrichtlinien Entwickler assoziieren manchmal ein Byte so, als ob es immer acht Bits enthält. Auf Hosts, auf denen der Zeichentyp 16 Bit ist, kann dies zu der falschen Annahme führen, dass die Anwendung von sizeof auf einen Zeichentyp den Wert 2 zurückgibt. Diese Probleme werden an anderer Stelle besprochen.

1093050cookie-checkMuss beim Manipulieren des Speichers mit sizeof( char ) multipliziert werden?

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

Privacy policy