949 Stimmen

Unterschied zwischen malloc und calloc?

Was ist der Unterschied zwischen:

ptr = malloc (MAXELEMS * sizeof(char *));

oder:

ptr = calloc (MAXELEMS, sizeof(char*));

Wann ist es eine gute Idee, calloc statt malloc zu verwenden oder umgekehrt?

48 Stimmen

9 Stimmen

In C könnte man die obige Aufgabe allgemeiner formulieren als: ptr = calloc(MAXELEMS, sizeof(*ptr));

8 Stimmen

Ein interessanter Beitrag über den Unterschied zwischen calloc und malloc+memset vorpus.org/blog/warum-besteht-calloc-exist

7voto

Vipin Diwakar Punkte 115

Le site calloc() Funktion, die in der Datei <stdlib.h> Kopfzeile bietet eine Reihe von Vorteilen gegenüber der malloc() Funktion.

  1. Es weist den Speicher als eine Anzahl von Elementen einer bestimmten Größe zu, und
  2. Er initialisiert den zugewiesenen Speicher, so dass alle Bits Null sind.

7voto

elmiomar Punkte 1577

malloc() y calloc() sind Funktionen aus der C-Standardbibliothek, die eine dynamische Speicherzuweisung ermöglichen, d. h., sie erlauben beide eine Speicherzuweisung während der Laufzeit.

Ihre Prototypen sind wie folgt:

void *malloc( size_t n);
void *calloc( size_t n, size_t t)

Es gibt hauptsächlich zwei Unterschiede zwischen den beiden:

  • Verhalten: malloc() weist einen Speicherblock zu, ohne ihn zu initialisieren, und das Lesen des Inhalts aus diesem Block führt zu Garbage-Werten. calloc() hingegen weist einen Speicherblock zu und initialisiert ihn mit Nullen, und das Lesen des Inhalts dieses Blocks führt natürlich zu Nullen.

  • Syntax: malloc() benötigt 1 Argument (die zuzuweisende Größe), und calloc() benötigt zwei Argumente (Anzahl der zuzuweisenden Blöcke und Größe der einzelnen Blöcke).

Der Rückgabewert von beiden ist ein Zeiger auf den zugewiesenen Speicherblock, falls erfolgreich. Andernfalls, NULL zurückgegeben, was das Scheitern der Speicherzuweisung anzeigt.

Beispiel:

int *arr;

// allocate memory for 10 integers with garbage values
arr = (int *)malloc(10 * sizeof(int)); 

// allocate memory for 10 integers and sets all of them to 0
arr = (int *)calloc(10, sizeof(int));

Die gleiche Funktionalität wie calloc() kann erreicht werden durch malloc() y memset() :

// allocate memory for 10 integers with garbage values   
arr= (int *)malloc(10 * sizeof(int));
// set all of them to 0
memset(arr, 0, 10 * sizeof(int)); 

Beachten Sie, dass malloc() wird vorzugsweise verwendet über calloc() da es schneller ist. Wenn eine Null-Initialisierung der Werte gewünscht ist, verwenden Sie calloc() stattdessen.

6voto

Ein Unterschied, der noch nicht erwähnt wurde: Größenbeschränkung

void *malloc(size_t size) kann nur bis zu SIZE_MAX .

void *calloc(size_t nmemb, size_t size); können bis zu etwa SIZE_MAX*SIZE_MAX .

Diese Fähigkeit wird bei vielen Plattformen mit linearer Adressierung nicht oft genutzt. Solche Systeme begrenzen calloc() con nmemb * size <= SIZE_MAX .

Betrachten wir einen Typ von 512 Bytes namens disk_sector und Code verwenden will Lose der Sektoren. Hier kann der Code nur bis zu SIZE_MAX/sizeof disk_sector Sektoren.

size_t count = SIZE_MAX/sizeof disk_sector;
disk_sector *p = malloc(count * sizeof *p);

Betrachten Sie das folgende Beispiel, das eine noch größere Zuweisung ermöglicht.

size_t count = something_in_the_range(SIZE_MAX/sizeof disk_sector + 1, SIZE_MAX)
disk_sector *p = calloc(count, sizeof *p);

Ob ein solches System nun eine so große Menge liefern kann, ist eine andere Frage. Die meisten werden es heute nicht können. Dennoch ist es seit vielen Jahren so, dass SIZE_MAX war 65535. Gegeben Mooresches Gesetz Ich vermute, dass dies um das Jahr 2030 bei bestimmten Speichermodellen der Fall sein wird. SIZE_MAX == 4294967295 und Speicherpools in der Größenordnung von 100 GBytes.

2 Stimmen

Im Allgemeinen ist size_t in der Lage, die Größe der größten Art von Objekt zu speichern, die ein Programm verarbeiten kann. Ein System, in dem size_t 32 Bits ist, wird wahrscheinlich nicht in der Lage sein, eine Zuweisung zu verarbeiten, die größer als 4294967295 Bytes ist, und ein System, das in der Lage wäre, Zuweisungen dieser Größe zu verarbeiten, würde fast sicher size_t größer als 32 Bit. Die einzige Frage ist, ob die Verwendung von calloc mit Werten, deren Produkt über SIZE_MAX kann man sich darauf verlassen, dass sie Null ergibt, anstatt einen Zeiger auf eine kleinere Zuweisung zurückzugeben.

0 Stimmen

Zustimmen über Ihre Verallgemeinerung Die C-Spezifikation erlaubt jedoch calloc() Zuweisungen, die über SIZE_MAX . Das ist in der Vergangenheit mit 16-Bit-Produkten passiert. size_t und da der Speicher immer billiger wird, sehe ich keinen Grund, warum dies nicht auch in Zukunft geschehen kann, selbst wenn es nicht gemeinsame .

1 Stimmen

Der C-Standard macht es möglich, dass Code Anfrage eine Zuteilung, deren Größe die SIZE_MAX . Es ist sicherlich nicht erforderlich, dass es irgendeinen Umstand gibt, unter dem eine solche Zuweisung erfolgreich sein könnte; ich bin mir nicht sicher, ob es einen besonderen Nutzen hat, wenn man vorschreibt, dass Implementierungen, die solche Zuweisungen nicht handhaben können, Folgendes zurückgeben müssen NULL (insbesondere angesichts der Tatsache, dass es bei einigen Implementierungen üblich ist, dass malloc geben Zeiger auf Speicherplatz zurück, der noch nicht festgelegt wurde und möglicherweise nicht verfügbar ist, wenn der Code ihn tatsächlich zu nutzen versucht).

0voto

Akshay V Punkte 13

Beide malloc y calloc Speicher zuweisen, aber calloc initialisiert alle Bits auf Null, während malloc nicht.

Calloc könnte man als Äquivalent zu malloc + bezeichnen. memset mit 0 (wobei memset die angegebenen Bits des Speichers auf Null setzt).

Wenn also eine Initialisierung auf Null nicht notwendig ist, könnte die Verwendung von malloc schneller sein.

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