Wie kamen malloc und calloc zu unterschiedlichen Signaturen? [duplicate]
Lesezeit: 5 Minuten
klar
Mögliches Duplikat:
Warum nimmt calloc zwei Argumente und malloc nur eines?
Es gibt viele von Ressourcen, die den Unterschied in der Funktionalität zwischen beschreiben malloc und callocaber ich kann nicht leicht einen finden, der die Geschichte hinter den unterschiedlichen Funktionssignaturen beschreibt:
Natürlich die size im ersteren ist die Größe für jedes Mitglied. Vielleicht war die Idee, dass die Mitgliedsgröße ein Vielfaches der Seitengröße ist callocs könnte faul über das Betriebssystem erfolgen?
(Ich kann mir ebenso gut Gründe ausdenken wie der nächste Typ – keine akzeptierten Antworten ohne zitierte Quellen. :-))
Extrem verwandt: stackoverflow.com/q/7536413/142019
– Benutzer142019
28. September 2011 um 9:47 Uhr
Keine Zitate, also nur ein Kommentar – die calloc Die Signatur ist brauchbarer, da eine ordnungsgemäße Implementierung beim Multiplizieren auf Überlauf prüft und den Aufrufer von der Verantwortung entlastet. Ich vermute eine von zwei Erklärungen: (1) malloc kam zuerst, und es ist nur eine Kompatibilitätssache, (2) calloc wird erwartet, dass es wegen des Nullstellens langsamer ist, und jemand dachte, dass die Multiplikation und der Überlauf einchecken malloc sollte aus Geschwindigkeitsgründen weggelassen werden.
– Steve Jessop
28. September 2011 um 9:49 Uhr
Ich finde es seltsam, dass eine Frage als exaktes Duplikat einer weniger spezifischen Frage ohne zufriedenstellende (oder akzeptierte) Antworten geschlossen werden kann – ich frage mich, wie die beiden Signaturen historisch entstanden sind.
– klar
28. September 2011 um 18:10 Uhr
James Greenhalgh
Dies ist etwas offen für die Interpretation der Sprache, die in der C-Spezifikation verwendet wird.
Die Sprache hier scheint sehr sorgfältig gewählt zu sein – malloc ist in Abschnitt 7.20.3.3 definiert als:
Die Funktion malloc weist einem Objekt Speicherplatz zu, dessen Größe durch size angegeben wird und dessen Wert unbestimmt ist.
Zuvor wurde ein Objekt in Abschnitt 3.14 wie folgt definiert:
Bereich der Datenspeicherung in der Ausführungsumgebung, dessen Inhalt Werte darstellen kann
calloc hingegen ist in 7.20.3.1 definiert als:
Die calloc-Funktion weist Platz für ein Array von nmemb-Objekten zu, deren Größe jeweils size ist. Der Raum wird auf alle Bits Null initialisiert.
Dies sollte es offensichtlich machen. Der Unterschied zwischen calloc und malloc besteht darin, dass calloc Speicher für ein Array von n konzeptuellen Objekten zuweist, obwohl sich dies in der Praxis nicht von einem Aufruf von malloc unterscheidet, der Speicherplatz für 1 konzeptionelles Objekt der Größe (n * Größe) zuweist.
Die nächste Frage ist also… was ist die Notwendigkeit für die Unterscheidung zwischen Platz für eine Reihe von Objekten und Platz für ein großes Objekt?
Aus Programmierersicht fragen die beiden Funktionsaufrufe nur nach unterschiedlichen Dingen. Einer verlangt, dass ein großes Stück Speicher zugewiesen wird – und ich werde mich darum kümmern. Der andere sagt – ich möchte ein Array von n Dingen dieser Größe, gib mir etwas Speicher, den ich für dieses Array verwenden könnte, und nulle es – weil ich in den meisten Implementierungen gute Annahmen darüber treffen kann, was null Speicher bedeutet.
Die Tatsache, dass Sie versuchen, es als malloc + Zeroing zu verwenden, ist nach meiner Lektüre der Spezifikation ein Missverständnis über den Zweck der Funktion.
Sie endeten mit unterschiedlichen Signaturen, weil sie unterschiedliche Dinge tun.
Einige nette Nebengedanken … Eine triviale Malloc-Implementierung kann wie folgt aussehen:
#define malloc(x) (calloc(1, x))
Es macht auch Spaß festzustellen, dass calloc mir kein Array von NULL-Zeigern zurückgibt, wenn meine NULL-Zeigerdarstellung nicht auf Null gesetzt ist. Besser noch, wenn ich eine Integer-Darstellung entwerfe, in der genullter Speicher nicht ((int)0 ist), gibt calloc mir kein Array von 0s zurück.
Das sagst du also im Grunde calloc gibt ein Array von initialisierten Objekten zurück (vorausgesetzt, dass All-Bits-Zero nicht garantiert ein gültiges Objekt für alle Typen in allen Implementierungen ist, ist es zumindest ein vernünftiger Initialisierungsversuch), wohingegen malloc gibt rohen, nicht initialisierten Speicher für ein Objekt oder ein Array zurück?
– Steve Jessop
28. September 2011 um 11:55 Uhr
In Bezug auf Ihre lustigen Notizen – Sie könnten tatsächlich eine Implementierung entwerfen, in der All-Bits-Zero eine Trap-Darstellung aller Typen außer ist char und signed/unsigned charWiedergabe calloc fast nutzlos. Als Folge davon calloc ist in streng konformen Programmen fast nutzlos, und sein zweiter Parameter ist in streng konformen Programmen völlig nutzlos, da die einzigen Typen, für die er nützlich ist, die Größe 1 haben.
– Steve Jessop
28. September 2011 um 12:01 Uhr
@Steve Jessop: Trap-Darstellungen sind kein Problem, solange Sie sie nicht auswerten – Sie können sie in einem streng konformen Programm problemlos überschreiben.
– Café
28. September 2011 um 12:29 Uhr
Bei Integer-Typen ist All-Bits-Zero immer eine Darstellung (vielleicht nicht die einzige) von 0. Dies wurde nicht im C90- oder C99-ISO-Standard angegeben, aber es wurde in einer der technischen Berichtigungen hinzugefügt (siehe n1256. pdf). Vermutlich fühlte sich das Komitee frei, diese Anforderung hinzuzufügen, da alle bestehenden Implementierungen sie bereits erfüllen. Für Floating- oder Pointer-Typen gibt es keine solche Garantie.
– Keith Thompson
28. September 2011 um 15:30 Uhr
@KeithThompson: Ist malloc(sizeof(double)) Garantiert eine gültig ausgerichtete zurückzugeben *double? Wie wäre es mit calloc(sizeof(double),1) [as distinct from calloc(1,sizeof(double))]? Während ich über jedes System überrascht wäre, bei dem Speicherzuweisungen nicht immer den Anforderungen für den längsten Typ entsprachen, würde ich denken, dass ein solches System nicht unbedingt verboten sein muss.
– Superkatze
27. Oktober 2012 um 19:29 Uhr
12909600cookie-checkWie kamen malloc und calloc zu unterschiedlichen Signaturen? [duplicate]yes
Extrem verwandt: stackoverflow.com/q/7536413/142019
– Benutzer142019
28. September 2011 um 9:47 Uhr
Keine Zitate, also nur ein Kommentar – die
calloc
Die Signatur ist brauchbarer, da eine ordnungsgemäße Implementierung beim Multiplizieren auf Überlauf prüft und den Aufrufer von der Verantwortung entlastet. Ich vermute eine von zwei Erklärungen: (1)malloc
kam zuerst, und es ist nur eine Kompatibilitätssache, (2)calloc
wird erwartet, dass es wegen des Nullstellens langsamer ist, und jemand dachte, dass die Multiplikation und der Überlauf eincheckenmalloc
sollte aus Geschwindigkeitsgründen weggelassen werden.– Steve Jessop
28. September 2011 um 9:49 Uhr
Ich finde es seltsam, dass eine Frage als exaktes Duplikat einer weniger spezifischen Frage ohne zufriedenstellende (oder akzeptierte) Antworten geschlossen werden kann – ich frage mich, wie die beiden Signaturen historisch entstanden sind.
– klar
28. September 2011 um 18:10 Uhr