wake-up-neo.net

Wann und warum Malloc verwenden?

Nun, ich kann nicht verstehen, wann und warum es erforderlich ist, Speicher mit malloc zuzuordnen.

Hier ist mein Code:

#include <stdlib.h>

int main(int argc, const char *argv[]) {

  typedef struct {
    char *name;
    char *sex;
    int age;
  } student;


  //Now I can do two things
  student p;

  //or
  student *ptr = (student *)malloc(sizeof(student));

  return 0;
}

Warum muss ich Speicher zuweisen, wenn ich einfach student p; verwenden kann?

43
pr1m3x

malloc wird für die dynamische Speicherzuordnung verwendet. Wie gesagt, handelt es sich um eine dynamische Zuordnung, was bedeutet, dass Sie den Speicher zur Laufzeit zuordnen. Zum Beispiel, wenn Sie nicht wissen, wie viel Speicher Sie während der Kompilierzeit haben. 

Ein Beispiel sollte dies klarstellen. Angenommen, Sie wissen, dass es maximal 20 Studenten geben wird. Sie können also ein Array mit statischen 20 Elementen erstellen. Ihr Array kann maximal 20 Studenten aufnehmen. Was aber, wenn Sie die Anzahl der Schüler nicht kennen? Angenommen, die erste Eingabe ist die Anzahl der Schüler. Es könnte 10, 20, 50 oder was auch immer sein. Nun nehmen Sie die Eingabe n = die Anzahl der Studenten zur Laufzeit und weisen diesen Speicher dynamisch mit malloc zu.

Dies ist nur ein Beispiel. Es gibt viele Situationen wie diese, in denen eine dynamische Zuordnung erforderlich ist.

Schau dir die Manpage malloc (3) an.

40
taskinoor

Sie verwenden malloc, wenn Sie Objekte zuordnen müssen, die über die Laufzeit der Ausführung des aktuellen Blocks hinaus existieren müssen (wo auch ein Copy-on-Return-Vorgang teuer wäre) oder wenn Sie Speicherplatz reservieren müssen, der größer als der Stapel dieses Stapels ist (Beispiel: Ein lokales Stack-Array von 3 MB ist eine Idee von bad).

Bevor C99 VLAs einführte, war es auch benötigt, um die Zuordnung eines Arrays mit dynamischer Größe durchzuführen. Das Erstellen von dynamischen Datenstrukturen wie Bäumen, Listen und Warteschlangen, die von vielen Systemen verwendet werden, sind jedoch erforderlich. Es gibt wahrscheinlich viele weitere Gründe, dies sind nur einige.

20
Necrolis

Wenn Sie die Struktur des Beispiels etwas erweitern, beachten Sie Folgendes:

#include <stdio.h>

int main(int argc, const char *argv[]) {

typedef struct {
 char* name;
 char* sex;
 char* insurace;
 int age;
 int yearInSchool;
 float tuitionDue;
}student;


//Now I can do two things
student p;

//or
student *p = (student *)malloc(sizeof(student));

return 0
}

C a ist eine Sprache, die implizit nach Wert und nicht nach Verweis weitergibt. Wenn wir in diesem Beispiel 'p' an eine Funktion übergeben, um etwas daran zu arbeiten, würden wir eine Kopie der gesamten Struktur erstellen. Dies verwendet zusätzlichen Speicher (insgesamt ist der erforderliche Speicherplatz für eine bestimmte Struktur erforderlich), ist langsamer und skaliert möglicherweise nicht gut (mehr dazu in einer Minute). Durch das Passieren von * p übergeben wir jedoch nicht die gesamte Struktur. Wir übergeben nur eine Adresse im Speicher, die auf diese Struktur verweist. Die Menge der übergebenen Daten ist geringer (Größe eines Zeigers), daher ist der Vorgang schneller.

Stellen Sie sich jetzt ein Programm (wie ein Schülerinformationssystem) vor, das einen Datensatz mit Tausenden oder sogar Zehntausenden erstellen und verwalten muss. Wenn Sie die gesamte Struktur nach Wert übergeben, dauert die Bearbeitung einer Datenmenge länger als nur einen Zeiger auf jeden Datensatz.

14
ArcticPhoenix

malloc = Speicherzuordnung.

Wenn Sie andere Programmiersprachen durchgearbeitet haben, haben Sie möglicherweise das Schlüsselwort 'new' verwendet.

Malloc macht genau das gleiche wie in C. Es braucht einen Parameter, welche Größe des Speichers zugewiesen werden muss, und es gibt eine Zeigervariable zurück, die auf den ersten Speicherblock des Befehls zeigt 

gesamten Speicherblock, den Sie im Speicher erstellt haben. Beispiel -

int *p = malloc(sizeof(int)*10);

Nun zeigt * p auf den ersten Block des nachfolgenden 20-Integer-Blocks, der im Speicher reserviert ist.

Sie können jeden Block mit den Operatoren ++ und - durchlaufen. Alles Gute.

4
Acn

In diesem Beispiel scheint es durchaus nutzlos zu sein. Stellen Sie sich nun vor, Sie verwenden Sockets oder eine Datei IO und müssen Pakete mit variabler Länge lesen, die Sie nur während des Laufens abschrecken können. Oder wenn Sie Sockets verwenden und jede Client-Verbindung etwas Speicherplatz auf dem Server benötigt. Sie könnten ein statisches Array erstellen, aber dies gibt Ihnen ein Clientlimit, das beim Kompilieren abschreckend wirkt.

0
DipSwitch

Versuchen wir, diese Frage unter Berücksichtigung verschiedener Aspekte anzugehen

Größe

Mit malloc können Sie viel größere Speicherplätze zuweisen, als einfach mit student p; oder int x[n]; zugewiesen werden. Der Grund dafür ist, dass malloc den Speicherplatz auf dem Heap reserviert, während der andere ihn auf dem Stack reserviert

Die Programmiersprache C verwaltet den Speicher statisch, automatisch oder dynamisch. Variablen mit statischer Dauer werden normalerweise zusammen mit dem ausführbaren Code des Programms im Hauptspeicher zugewiesen und bleiben während der gesamten Lebensdauer des Programms erhalten. Variable mit automatischer Dauer werden auf dem Stack zugewiesen und kommen und gehen, wenn Funktionen aufgerufen und zurückgegeben werden. Bei Variablen mit statischer Dauer und automatischer Dauer muss die Größe der Zuweisung konstant sein (außer bei automatischen Arrays mit variabler Länge [5]). Wenn die erforderliche Größe erst zur Laufzeit bekannt ist (z. B. wenn Daten beliebiger Größe vom Benutzer oder von einer Plattendatei gelesen werden), ist die Verwendung von Datenobjekten mit fester Größe nicht ausreichend. ( aus Wikipedia )

Umfang

Normalerweise werden die deklarierten Variablen nach dem Block, in dem sie deklariert wurden, gelöscht/freigegeben (sie werden im Stapel deklariert). Andererseits bleiben Variablen, deren Speicher mit malloc zugewiesen wurde, bis sie manuell freigegeben werden.

Dies bedeutet auch, dass Sie keine Variablen/Arrays/Strukturen in einer Funktion erstellen und deren Adresse zurückgeben können (da der Speicher, auf den sie verweist, möglicherweise freigegeben wird). Der Compiler versucht Sie auch mit einer Warnung zu warnen:

Warnung - Adresse des Stapelspeichers, die der lokalen Variablen 'Matches' zugeordnet ist

Für mehr Details lies diese

Größe ändern (realloc)

Wie Sie vielleicht schon erraten haben, ist dies auf normale Weise nicht möglich

Fehlererkennung

Falls kein Speicher zugewiesen werden kann: Normalerweise wird Ihr Programm beendet, während malloc eine NULL zurückgibt, die leicht abgerufen und in Ihrem Programm verarbeitet werden kann

Ändern Sie in Zukunft den String-Inhalt

Wenn Sie einen String wie char *some_memory = "Hello World"; erstellen, können Sie some_memory[0] = 'h'; nicht ausführen, da er als String-Konstante gespeichert wird und der Speicher, in dem er gespeichert ist, schreibgeschützt ist. Wenn Sie stattdessen malloc verwenden, können Sie den Inhalt später ändern. Für weitere Informationen überprüfen Sie diese Antwort

Weitere Informationen zu Arrays mit variabler Größe finden Sie unter siehe dazu

0
Daksh Shah