2009-10-08 11 views
7

Wenn ich einen Kommentar zu einer anderen Antwort von mir here beantworte, fand ich, was ich denke kann ein Loch im C-Standard sein (c1x, ich habe die früheren und nicht überprüft Ja, ich weiß, es ist unglaublich unwahrscheinlich, dass ich alleine unter allen Bewohnern des Planeten einen Fehler im Standard gefunden habe. Informationen folgen:Mögliches Problem mit C Standard malloc'ing Zeichen

  1. Abschnitt 6.5.3.4 ("Die Größe des Betreibers") Para 2 Staaten "The sizeof operator yields the size (in bytes) of its operand".
  2. Absatz 3 dieses Abschnitts besagt: "When applied to an operand that has type char, unsigned char, or signed char, (or a qualified version thereof) the result is 1".
  3. Abschnitt 7.20.3.3 beschreibt void *malloc(size_t sz) aber alles, was es sagt, ist "The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate". Es wird überhaupt nicht erwähnt, welche Einheiten für das Argument verwendet werden.
  4. Anhang E beginnt die 8 ist die Minimum Wert für CHAR_BIT so Zeichen können mehr als ein Byte lang sein.

Meine Frage ist einfach:

In einer Umgebung, in ein char 16 Bit breit ist, wird malloc(10 * sizeof(char)) 10 Zeichen zuweisen (20 Byte) oder 10 Bytes? Punkt 1 scheint auf erstere hinzuweisen, Punkt 2 zeigt letzteres an.

Wer mit mehr C-Standard-fu als ich habe eine Antwort dafür?

Antwort

16

in einem 16-Bit-Umgebung charmalloc(10 * sizeof(char)) wird zuzuteilen char 10 s (10 Bytes), weil, wenn char 16 Bits, so daß die Architektur/Umsetzung eines Bytes als 16 Bit definiert. A char ist kein Oktett, es ist ein Byte. Auf älteren Computern kann dies größer sein als der 8-Bit de-facto Standard, den wir heute haben.

Der relevante Abschnitt von dem C-Standard folgt:

3,6 Begriffe, Definitionen und Symbole

byte - adressierbare Einheit der Datenspeicher groß genug, um ein Mitglied des Grundzeichensatzes der Ausführung zu halten, environment ...

HINWEIS 2 - Ein Byte besteht aus einer zusammenhängenden Bitfolge, deren Nummer implementierungsdefiniert ist.

+1

Eigentlich glaube ich, dass Sie es dort haben können. basierend auf Ihrer Antwort fand ich 3.6 (in "Begriffe, Definitionen und Symbole") mit der Angabe "byte - adressierbare Datenspeichereinheit, die groß genug ist, um jedes Element des grundlegenden Zeichensatzes der Ausführungsumgebung aufzunehmen ..." ANMERKUNG 2 - Ein Byte besteht aus einer zusammenhängenden Folge von Bits, deren Anzahl implementierungsdefiniert ist ". – paxdiablo

+0

Verdammt, denke an den Ruhm und die Auszeichnungen, die ich bekommen hätte, um ein Problem im Standard zu finden. Na ja, zurück zum Tagesjob :-) – paxdiablo

+0

Wieder einmal wiederhole ich das Mantra "Ich brauche eine Kopie des Standards". Ich füge Ihr Standardangebot zu meiner Antwort für die Vollständigkeit hinzu. –

1

Sind die Einheiten von "size_t sz" nicht in der adressierbaren Einheit Ihrer Architektur? Ich arbeite mit einem DSP, dessen Adressen 32-Bit-Werten entsprechen, nicht Bytes. malloc (1) ruft einen Zeiger auf einen 4-Byte-Bereich ab.

+1

In Bezug auf die Formulierung in der C-Norm ist ein "Byte" auf dieser Architektur 32 Bits. Das etwas verwirrende, was der C-Standard ein "Byte" nennt, entspricht nicht unbedingt der (heute üblichen) Verwendung des Wortes. – caf

+1

Und aus dem gleichen Grund, wenn Netzwerkstandards "8 Bits" bedeuten, sagen sie "Oktett", nicht "Byte". Nur in Einzelhandelskontexten ist ein Byte eindeutig 8 Bits, wie in "MB der Bandbreite", "GB RAM", "TB des Plattenplatzes". –

+0

Ah, das macht Sinn. Ich denke, wir sind mit der Zweideutigkeit für Nicht-Sprach-Anwälte beschäftigt, da Wörter wie "Megaoktetts" oder "Kibioktets" nicht besonders gut fließen. – twon33

2

die strenge Korrelation zwischen Bytes wird char und Objektgröße in 6.2.6.1/4 In dem C99-Standard gegeben „Darstellungen von Arten - allgemein“:

Werte in nicht-Bitfeld Objekten gespeichert eines anderen Objekttyps bestehen aus n × CHAR_BIT Bits, wobei n die Größe eines Objekts dieses Typs in Bytes ist. Der Wert kann in ein Objekt des Typs unsigned char [n] kopiert werden (z. B. durch memcpy); Der resultierende Satz von Bytes wird als Objektdarstellung des Werts bezeichnet.

Im ++ Standard C die gleiche Beziehung in 3,9/2 "Typen" gegeben:

für jedes Objekt (andere als eine Basisklasse Subobjekt) des POD-Typ T, ob die Objekt enthält einen gültigen Wert vom Typ T, die zugrunde liegenden Bytes (1.7), aus denen das Objekt besteht, können in ein Array aus char oder unsigned char kopiert werden. Wenn der Inhalt des Arrays von char oder unsigned char in das Objekt zurückkopiert wird, muss das Objekt anschließend seinen ursprünglichen Wert beibehalten.

In C90 scheint es nicht so explizit erwähnt Korrelation zu werden, sondern zwischen der Definition eines Bytes, die Definition eines Zeichens, und die Definition des sizeof Operator kann der Schluss gemacht werden, dass ein char Typ entspricht einem Byte.

Beachten Sie auch, dass die Anzahl der Bits in einem Byte (und die Anzahl der Bits in einem char) Implementierung definiert ist — streng genommen muss es nicht 8 Bits sein. Und onybone weist in einem Kommentar an anderer Stelle darauf hin, dass DSPs häufig Bytes mit einer Anzahl von Bits haben, die nicht 8 sind.

Beachten Sie, dass IETF RFCs und Standards allgemein (immer?) Den Begriff 'Octect' anstelle von 'Byte' verwenden um eindeutig zu sein, dass die Einheiten, über die sie sprechen, genau 8 Bits haben - nicht mehr und nicht weniger.

+0

+1. Es ist erwähnenswert, dass der Standard die * untere * Grenze von CHAR_BITS festlegt, aber nicht die obere. Also muss es mindestens 8 sein. – paxdiablo