Ich verstehe, wie malloc () funktioniert. Meine Frage ist, ich werde solche Dinge sehen:
#define A_MEGABYTE (1024 * 1024)
char *some_memory;
size_t size_to_allocate = A_MEGABYTE;
some_memory = (char *)malloc(size_to_allocate);
sprintf(some_memory, "Hello World");
printf("%s\n", some_memory);
free(some_memory);
Der Kürze halber habe ich die Fehlerprüfung weggelassen. Meine Frage ist, können Sie das nicht einfach tun, indem Sie einen Zeiger auf einen statischen Speicher im Speicher initialisieren? vielleicht:
char *some_memory = "Hello World";
Ab wann müssen Sie den Speicher tatsächlich selbst zuweisen, anstatt die Werte zu deklarieren / zu initialisieren, die Sie beibehalten müssen?
c
memory
memory-management
Randombits
quelle
quelle
malloc()
fehlschlagen können!Antworten:
erstellt einen Zeiger auf eine Zeichenfolgenkonstante. Das bedeutet, dass sich die Zeichenfolge "Hello World" irgendwo im schreibgeschützten Teil des Speichers befindet und Sie nur einen Zeiger darauf haben. Sie können die Zeichenfolge als schreibgeschützt verwenden. Sie können keine Änderungen daran vornehmen. Beispiel:
Bittet um Ärger.
Andererseits
weist diesem zugewiesenen Speicher ein char-Array (eine Variable) und some_memory-Punkte zu. Jetzt ist dieses Array sowohl Lesen als auch Schreiben. Sie können jetzt tun:
und der Inhalt des Arrays ändert sich zu "Hallo Welt"
quelle
const char *s = "hi";
Ist dies nicht tatsächlich vom Standard vorgeschrieben?const char const* s;
Für genau dieses Beispiel ist Malloc von geringem Nutzen.
Der Hauptgrund, warum malloc benötigt wird, ist, wenn Sie Daten haben, deren Lebensdauer sich vom Codebereich unterscheidet. Ihr Code ruft malloc in einer Routine auf, speichert den Zeiger irgendwo und ruft schließlich in einer anderen Routine frei auf.
Ein zweiter Grund ist, dass C nicht wissen kann, ob auf dem Stapel noch genügend Platz für eine Zuordnung vorhanden ist. Wenn Ihr Code 100% robust sein muss, ist es sicherer, malloc zu verwenden, da Ihr Code dann erkennen kann, dass die Zuordnung fehlgeschlagen ist, und damit umgehen kann.
quelle
malloc ist ein wunderbares Tool zum Zuweisen, Neuzuweisen und Freigeben von Speicher zur Laufzeit im Vergleich zu statischen Deklarationen wie Ihrem Hallo-Welt-Beispiel, die zur Kompilierungszeit verarbeitet werden und daher nicht in der Größe geändert werden können.
Malloc ist daher immer dann nützlich, wenn Sie mit Daten beliebiger Größe wie dem Lesen von Dateiinhalten oder Sockets arbeiten und sich der Länge der zu verarbeitenden Daten nicht bewusst sind.
In einem trivialen Beispiel wie dem, das Sie gegeben haben, ist malloc natürlich nicht das magische "richtige Werkzeug für den richtigen Job", aber für komplexere Fälle (z. B. Erstellen eines Arrays beliebiger Größe zur Laufzeit) ist dies der einzige Weg gehen.
quelle
Wenn Sie die genaue Größe des zu verwendenden Speichers nicht kennen, benötigen Sie eine dynamische Zuordnung (
malloc
). Ein Beispiel könnte sein, wenn ein Benutzer eine Datei in Ihrer Anwendung öffnet. Sie müssen den Inhalt der Datei in den Speicher lesen, aber natürlich kennen Sie die Größe der Datei nicht im Voraus, da der Benutzer die Datei zur Laufzeit vor Ort auswählt. Grundsätzlich benötigenmalloc
Sie also, wenn Sie die Größe der Daten, mit denen Sie arbeiten, nicht im Voraus kennen. Zumindest ist dies einer der Hauptgründe für die Verwendungmalloc
. In Ihrem Beispiel mit einer einfachen Zeichenfolge, deren Größe Sie zum Zeitpunkt der Kompilierung bereits kennen (und die Sie nicht ändern möchten), ist es wenig sinnvoll, diese dynamisch zuzuweisen.Etwas abseits des Themas, aber ... Sie müssen sehr vorsichtig sein, um bei der Verwendung keine Speicherlecks zu verursachen
malloc
. Betrachten Sie diesen Code:Sehen Sie, was mit diesem Code nicht stimmt? Es gibt eine bedingte Rückgabeanweisung zwischen
malloc
undfree
. Es mag zunächst in Ordnung erscheinen, aber denken Sie darüber nach. Wenn ein Fehler auftritt, kehren Sie zurück, ohne den von Ihnen zugewiesenen Speicher freizugeben. Dies ist eine häufige Ursache für Speicherlecks.Natürlich ist dies ein sehr einfaches Beispiel, und es ist sehr leicht, den Fehler hier zu erkennen, aber stellen Sie sich Hunderte von Codezeilen vor, die mit Zeigern,
malloc
s,free
s und allen Arten der Fehlerbehandlung übersät sind . Die Dinge können sehr schnell sehr chaotisch werden. Dies ist einer der Gründe, warum ich in anwendbaren Fällen modernes C ++ gegenüber C sehr bevorzuge, aber das ist ein ganz anderes Thema.Stellen Sie daher bei
malloc
jeder Verwendung sicher, dass Ihr Speicher so wahrscheinlichfree
wie möglich ist.quelle
ist illegal, String-Literale sind
const
.Dadurch wird ein 12-Byte-Zeichenarray auf dem Stapel oder global zugewiesen (je nachdem, wo es deklariert ist).
Wenn Sie Platz für weitere Manipulationen lassen möchten, können Sie festlegen, dass das Array größer sein soll. (Bitte legen Sie jedoch nicht 1 MB auf den Stapel.)
quelle
Ein Grund, warum der Speicher zugewiesen werden muss, besteht darin, dass Sie ihn zur Laufzeit ändern möchten. In diesem Fall kann ein Malloc oder ein Puffer auf dem Stapel verwendet werden. Das einfache Beispiel für die Zuweisung von "Hello World" zu einem Zeiger definiert Speicher, der "normalerweise" zur Laufzeit nicht geändert werden kann.
quelle