2788 Stimmen

Muss ich das Ergebnis von malloc casten?

En diese Frage schlug jemand in einer Kommentar dass ich no werfen das Ergebnis von malloc . d.h., ich sollte dies tun:

int *sieve = malloc(sizeof(*sieve) * length);

statt:

int *sieve = (int *) malloc(sizeof(*sieve) * length);

Warum sollte dies der Fall sein?

35 Stimmen

9 Stimmen

Gussformen sind böse. Ich sehe so viele Abdrücke im Code, die nur das Ergebnis einer schlechten Programmierpraxis sind. Wann immer Sie einen Cast einfügen müssen, sollten Sie sich als erstes fragen, was hier falsch ist. Ist alles so deklariert, wie es sein sollte? Wenn ja, wäre kein Cast erforderlich, also ist etwas falsch deklariert. Wenn Sie wirklich etwas auf niedriger Ebene mit einzelnen Bytes in einem int oder so tun müssen, ziehen Sie eine Union in Betracht, um auf sie zuzugreifen. Das wird sie genau richtig deklarieren. Als Faustregel gilt: Fügen Sie sie nicht ein, es sei denn, der Compiler beschwert sich. Dann vermeiden Sie sie. Dieses Beispiel wird sich nicht beschweren. void pointer wird zu jedem Typ promoten.

2 Stimmen

@HansLepoeter in C++ sind diese für malloc erforderlich, was meine Vermutung stützt, dass damit etwas nicht stimmt

59voto

user968000 Punkte 1655

Es ist nicht zwingend erforderlich, die Ergebnisse der malloc denn es liefert void* und eine void* kann auf einen beliebigen Datentyp verweisen.

3 Stimmen

Es ist nicht die Tatsache, dass void* die dies ermöglicht; es ist die Tatsache, dass ein void* kann sein stillschweigend umgerechnet zu jedem anderen Zeigertyp. Um die Unterscheidung zu verdeutlichen, wird in C++ ein void* kann immer noch auf irgendetwas zeigen, aber die implizite Konvertierung wurde abgeschafft, so dass man einen Wurf machen muss.

44voto

Slothworks Punkte 1043

Das ist es, was Die GNU C Bibliothek Referenz sagt das Handbuch:

Sie können das Ergebnis von malloc in jede Zeigervariable ohne ein umgewandelt, da ISO C den Typ automatisch konvertiert void * zum anderen Zeigertyp umzuwandeln, wenn dies erforderlich ist. Der Cast ist jedoch in anderen Kontexten notwendig anderen Kontexten als Zuweisungsoperatoren oder wenn Sie möchten, dass Ihr Code in traditionellem C.

Und tatsächlich ist die ISO C11-Norm (S. 347) sagt dies:

Der Zeiger, der bei erfolgreicher Zuweisung zurückgegeben wird, ist entsprechend ausgerichtet, so dass dass er einem Zeiger auf einen beliebigen Objekttyp zugewiesen werden kann, der eine grundlegenden Ausrichtungsanforderung zugewiesen und dann für den Zugriff auf ein solches Objekt oder ein Array solcher Objekte in dem zugewiesenen Bereich zugreifen kann (bis der Platz explizit freigegeben wird)

40voto

Endeavour Punkte 515

Ein ungültiger Zeiger ist ein allgemeiner Objektzeiger, und C unterstützt die implizite Konvertierung von einem ungültigen Zeigertyp in andere Typen, so dass eine explizite Typisierung nicht erforderlich ist.

Wenn Sie jedoch wollen, dass derselbe Code auf einer C++-Plattform, die keine implizite Konvertierung unterstützt, perfekt kompatibel ist, müssen Sie die Typisierung vornehmen.

3 Stimmen

Es ist kein normaler Anwendungsfall, einen einzigen Quellcode sowohl in C als auch in C++ zu kompilieren (im Gegensatz zur Verwendung einer Header-Datei, die Deklarationen enthält, um C- und C++-Code miteinander zu verknüpfen). Verwendung von malloc und Freunde in C++ ist ein gutes Warnzeichen dafür, dass es besondere Aufmerksamkeit verdient (oder in C neu geschrieben werden muss).

2 Stimmen

"Ein ungültiger Zeiger ist ein generischer Zeiger" --> "Ein ungültiger Zeiger ist ein generischer Zeiger Objekt Zeiger". Die Größe von Funktionszeigern kann folgende Werte überschreiten void * daher void * ist nicht ausreichend, um einen Funktionszeiger gut zu speichern.

34voto

Jeyamaran Punkte 748

Das hängt von der Programmiersprache und dem Compiler ab. Wenn Sie malloc in C, ist es nicht notwendig, es zu casten, da es automatisch casten wird. Wenn Sie jedoch C++ verwenden, sollten Sie cast eingeben, da malloc gibt eine void* Typ.

4 Stimmen

Die Funktion malloc gibt auch in C einen ungültigen Zeiger zurück, aber die Regeln der Sprache unterscheiden sich von denen in C++.

32voto

swaps Punkte 580

Der zurückgegebene Typ ist void*, der in den gewünschten Typ eines Datenzeigers umgewandelt werden kann, um dereferenzierbar zu sein.

3 Stimmen

void* kann in den gewünschten Typ umgewandelt werden, aber das ist nicht nötig, da es automatisch umgewandelt wird. Die Umwandlung ist also nicht notwendig und aus den in den Antworten mit hoher Punktzahl genannten Gründen sogar unerwünscht.

1 Stimmen

Aber nur, wenn Sie sie "on the fly" dereferenzieren müssen. Wenn Sie stattdessen eine Variable erzeugen, wird sie sicher und automatisch in den effektiven Typ der Variablen umgewandelt, ohne Casting (in C).

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X