Wie kamen malloc und calloc zu unterschiedlichen Signaturen? [duplicate]

Lesezeit: 5 Minuten

Benutzer-Avatar
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:

   void *calloc(size_t nmemb, size_t size);
   void *malloc(size_t size);

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

Benutzer-Avatar
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

1290960cookie-checkWie kamen malloc und calloc zu unterschiedlichen Signaturen? [duplicate]

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

Privacy policy