Was benötigt man für die Parameter "nmem" und "size" in C-Funktionen? [Duplikat]

8

Ich habe dies bei vielen C-Funktionen bemerkt, insbesondere bei solchen, die sich mit Speicher- oder Dateioperationen beschäftigen, aber nicht alle verwenden beide Parameter. Zum Beispiel wird malloc ein Parameter übergeben, die Größe in Byte des benötigten Speicherplatzes. Calloc auf der anderen Seite wird zwei Parameter übergeben, die Größe in Bytes eines Elements und die Anzahl der Elemente (Größe und nmem). Es gibt andere Funktionen, die diese Größen- und nmem-Parameter ebenfalls verwenden.

Im Wesentlichen würde der Calloc Call die gleiche Menge an Speicher wie malloc (nmem size) zuweisen, so dass alles, was wirklich passiert, der Stern () ist, wird durch ein Komma (,) ersetzt. Zumindest kann ich das auf der höheren Ebene, an der ich arbeite, nicht sagen. Ich sehe keinen Unterschied zum Aufruf von Calloc (1, nmem Größe), Calloc (nmem Größe, 1) oder Calloc (nmem, Größe).

Gibt es tatsächlich etwas auf einer niedrigeren Ebene, was dazu führt, dass Aufruf von Calloc (1, nmem * size) sich grundlegend von Calloc (nmem, size) unterscheidet?

Bearbeiten: Ich kenne den funktionalen Unterschied zwischen Calloc und Malloc. Ich bin interessiert, warum es Unterschiede in den Parametern gibt. Es gibt andere Funktionen, die 2 Größenparameter für die Gesamtgröße verwenden (fread, fwrite, etc). Mir geht es nicht um die spezifischen Funktionen, sondern darum, warum es zwei Parameter für die Gesamtgröße gibt, die in der Funktion verwendet werden, wenn im Wesentlichen die Gesamtgröße zu den zwei miteinander multiplizierten Parametern wird. Ich finde die meiste Zeit, wenn ich diese Funktionen verwende, benutze ich die Größe, die ich im Parameter "size" brauche und eine "1" für den Parameter "nmem" (manchmal "count" usw.).

    
Chris 12.10.2012, 16:02
quelle

2 Antworten

2

In einem Kommentar zu der Frage habe ich geschrieben, dass calloc() eine bessere Speicherausrichtung für Plattformen ermöglicht, auf die es ankommt. Ich konnte (noch) nichts finden, was dies unterstützen würde. Ich bin mir ziemlich sicher, dass es ein Feature des VMS / VAXC-Compilers war, aber die Quelle dafür ist knapp.

Ich fand jedoch, dass calloc() und alloc() zur gleichen Zeit erschienen, mit der Veröffentlichung von Unix V6 im Mai 1975. In V5, das 11 Monate zuvor veröffentlicht wurde, ist keine Funktion vorhanden; Die Kernel und Laufzeitbibliothek (und Assembler und C-Compiler) wurden in Assembly geschrieben.

In der Version V6 wurde Calloc implementiert als das vierzeilige Quellcodemodul:

%Vor%

calloc() löscht den zugewiesenen Speicher nicht; siehe alloc() , und es gab keine man Seite für calloc() in V6; jedoch die Manpage für alloc() :

  

DESCRIPTION
Alloc und free bieten ein einfaches universelles Core-Management-Paket.    Alloc hat eine Größe in Bytes; es gibt einen Zeiger auf einen Bereich mindestens der Größe zurück, die   ist gerade und kann daher ein Objekt jeder Art halten. Das Argument zu frei   ist ein Zeiger auf einen zuvor von alloz zugewiesenen Bereich; Dieser Bereich wird für die weitere Zuweisung zur Verfügung gestellt.

     

Unnötig zu sagen, dass eine ernsthafte Störung entstehen wird, wenn der Raum   zugewiesen von alloc wird überlaufen oder wenn eine zufällige Zahl an frei übergeben wird.

     

Die Routine verwendet einen First-Fit-Algorithmus, der das Zusammenführen von Blöcken mit anderen zusammenführt   Blöcke bereits frei. Es ruft sbrk auf (siehe "break (II))"   um mehr Kern aus dem System zu bekommen, wenn kein geeigneter Platz bereits frei ist.

     

DIAGNOSE
  Gibt -1 zurück, wenn kein Kern verfügbar ist.

     

Fehler   Zugeordneter Speicher enthält Müll, anstatt gelöscht zu werden.

Nicht einmal NULL wird bei Speichermangel zurückgegeben!

calloc() erscheint formal zuerst in UNIX V7, Januar 1979, zusammen mit einigen anderen Verbesserungen :

  • calloc() löscht den zurückgegebenen Speicher.
  • alloc() wurde in malloc() umbenannt
  • realloc() ist erschienen
  • im Fall der Speicherauslastung oder eines Heap-Fehlers, die Funktionen "geben einen Nullzeiger (0)"
  • zurück
wallyk 12.10.2012 18:15
quelle
0
  

Gibt es tatsächlich etwas auf einer niedrigeren Ebene, was dazu führt, dass Aufruf von Calloc (1, nmem * size) sich grundlegend von Calloc (nmem, size) unterscheidet?

Dieser Versuch, Dinge zu erklären, ist rein von der libc-Implementierung abhängig - und daher bei der Einschätzung eines bestimmten libc-Autors belassen:

Da calloc() den Speicher auf Null setzt, könnte das Grundprinzip sein, dass es möglicherweise mehr Zyklen bei einer mult verschwendet.

Im Gegensatz dazu wird malloc() eine Chance gegeben, einen vorausberechneten Wert zu verwenden, was möglicherweise den Overhead in einem Aufruf reduziert, der einfacher zu erfüllen ist.

Vergessen Sie nicht, dass C zu einem Zeitpunkt entwickelt wurde, an dem jeder CPU-Zyklus viel kostet - daher ein sehr schlankes Design im Vergleich zu vielen anderen "höheren" Sprachen.

Diese Frage könnte wahrscheinlich besser vom Autor von C Dennis Ritchie beantwortet werden.

    
Gil 12.10.2012 16:28
quelle

Tags und Links