Doppelsternchen und 'malloc' in C

8

Ich habe seit einiger Zeit Hinweise studiert und ich kann meinen Kopf nicht vollständig umschließen. Es scheint eine Lücke zu geben, die nicht erklärt wird, wenn Sie von Tutorials springen, die Zeiger auf tatsächliche Funktionen und Code erklären, von denen Sie annehmen, dass Sie sie kennen. Das Stück Code, das mich ärgert, ist wie folgt:

%Vor%

Okay, mein Verständnis ist wie folgt,

%Vor%

Von dem, was ich weiß, gibt malloc () einen Zeiger auf den Anfang des Speichers zurück, der gerade zugewiesen wurde, der einen Größenwert gleich der Größe eines Zeigers auf ein Zeichen (char *) hat. Sollte nun kein Zeiger auf den Anfang des Speichers ein einziges * haben? Wenn ja, wie können wir etwas mit einem * einem ** zuordnen? Ich bin ziemlich verwirrt, wenn irgendjemand eine Klarstellung geben könnte und vielleicht mit etwas Einblick in den Erinnerungsteil, der sehr nett wäre.

    
FShiwani 22.03.2017, 03:34
quelle

5 Antworten

4

Ihr Codeblock ist korrekt. Mit dieser Erklärung:

  

char **output_str = malloc(sizeof(char*));

output_str ist ein char-Zeiger auf einen char-Zeiger, oder er könnte als ein 2D-Array von Zeichen oder eine Matrix von Zeichen gesehen werden.

Grafisch dargestellt:

%Vor%

Stellen Sie sich den Speicher als ein sehr großes Array vor, in dem Sie auf Positionen durch seine Speicheradresse zugreifen können (in diesem Fall haben wir die Adressen zu natürlichen Zahlen vereinfacht. In Wirklichkeit sind es hexadezimale Werte) ). "n" ist die Gesamtmenge (oder Größe) des Speichers. Da Speicher in 0 zählt und startet, entspricht die Größe n-1.

1. Wenn Sie Folgendes aufrufen:

  

char **output_str = malloc(sizeof(char*));

Das Betriebssystem und der C-Compiler machen es für uns, aber wir können denken, dass unser Speicher geändert wurde. Z.B. Die Speicheradresse 3 hat jetzt einen char-Zeiger auf einen Zeichenzeiger namens output_str . .

%Vor%

2. Wenn wir jetzt sagen:

  

*output_str = malloc(sizeof(char));

Der Speicher wurde erneut geändert. Z.B. Die Speicheradresse 0 hat jetzt einen Zeichenzeiger namens *output_str .

%Vor%

3. Wir deklarieren ein statisch instanziertes Zeichen:

  

char a = 'a';

Also wieder hat sich unser Gedächtnis verändert, es hat sich bei MemoryAddress [6] = 'a':

platziert %Vor%
  

Zum Schluss rufen wir *output_str = &a; auf. Wir sagen nun dem char pointer *output_str , auf den zuvor instanziierten char a zu zeigen / zu verweisen.

Also wird unser letztes Gedächtnis so aussehen:

%Vor%

Weitere Informationen

%Vor%
    
0xDEFACED 22.03.2017, 04:08
quelle
2

Das ist ein echter Zweifel. Ich werde es am besten versuchen, um es dir klarzumachen. Aus den Details in Ihrer Frage nehme ich an (gelesen, "ziemlich sicher"), dass Sie malloc bei einem Speicher und dem jeweiligen Rückgabetyp verstehen.

Sie haben Zweifel, dass, wenn malloc einen Zeiger ( void* ) zurückgibt, wie kann es in einen Zeiger auf Zeiger ( char** ) umgewandelt werden.

  1. char **output_str entspricht char *(*output_str) , was bedeutet, dass *output_str ein Zeiger auf einige Daten vom Typ char ist. Also, das ist, was malloc zu ihm zurückkehrt.
  2. Auch hier sehen Sie, dass malloc einen Zeiger zurückgibt. Aber im Wesentlichen haben Sie einen Speicher für einen Zeiger auf char ( char* ) zugewiesen, der "wörtlich" bedeutet, dass malloc einen Zeiger ( void* ) an einen Speicher zurückgibt, an dem Sie char* haben Es ist ein Zeiger auf den Zeiger auf char , dh char** .
Abhineet 22.03.2017 04:24
quelle
0

Stellen Sie sich output_char als Zeiger auf ein Array von Zeichenfolgen vor, und jede Zeichenfolge ist ein Zeiger auf ein Array von Zeichen. Wenn Sie malloc (sizeof (char *)) ausführen, stellen Sie nur ein Array von char-Zeigern der Länge 1 bereit, sodass * output_char einen einzelnen nicht initialisierten Zeiger (NULL) enthält.

Was Sie tun sollten, ist genug Zeiger zuzuweisen, so dass Sie auf eine Reihe von Strings zeigen können. Angenommen, Sie möchten N Zeichenfolgen speichern, die alle von output_char referenziert werden. Initialisieren Sie es als:

%Vor%

Dann müssen Sie Speicher für jede dieser Zeichenfolgen zuweisen:

%Vor%

Es gibt ein gutes Beispiel dafür am Anfang jedes C-Programms:

%Vor%

Jedes C-Programm beginnt mit dieser Hauptdefinition. Er akzeptiert zwei Parameter. Einer ist die Anzahl der Strings, die über die Befehlszeile (einschließlich des Programmnamens) an Ihr Programm übergeben werden, und argv ist ein Verweis auf ein Array von String-Parametern.

Beispiel: Aufruf von myprog mit den folgenden Befehlszeilenparametern:

%Vor%

Ergebnisse in main () übergeben argc und argv so dass:

%Vor%     
ScottK 22.03.2017 04:00
quelle
0

malloc() gibt void * zurück, das implizit in jeden anderen Zeigertyp konvertiert werden kann. In Ihrem Fall kann der von malloc() zugewiesene Speicherplatz als Speicher für einen char * -Wert verwendet werden. Überprüfen Sie das Beispiel unten

%Vor%     
jjb 22.03.2017 03:56
quelle
0

Eine einfache Lösung zum Verständnis von malloc:

malloc (sizeof ( Each_Element ) * Number_Of_Elements ) gibt eine Adresse (aka: einen Zeiger) eines neuen Puffers zurück. Und in diesem Puffer hat jedes Element die gleiche Größe: sizeof ( Each_Element ) und Number_Of_Elements -Elemente.

Zum Beispiel:

malloc (sizeof (char)) gibt einen Zeiger eines Zeichens zurück.

malloc (sizeof (char) * 3) gibt einen Zeiger auf ein Zeichen zurück, das das erste Element eines char-Arrays ist und 3 Zeichen enthält.

malloc (sizeof (char *) * 6) gibt einen Zeiger eines char-Zeigers zurück, der das erste Element eines char-Zeigerarrays mit 6 Zeichenzeigern ist.

Im Grunde gibt malloc (sizeof (WHAT)) einen Zeiger auf WHAT zurück. Also einfach verstehen: malloc (Sizeof (WAS)) gibt (WAS *) zurück. malloc (Sizeof (WAS *)) gibt (WAS **) ... und so weiter zurück.

Beachten Sie, dass malloc tatsächlich einen Zeiger (void *) zurückgibt. Ein Zeiger (Void *) kann später auf eine beliebige Art von Zeiger umgewandelt werden. Es gibt also eine gute Methode für VisualStudio-Benutzer: int * pbuff = (int *) malloc (sizeof (int) * 6); Die (int *) before Funktion malloc konvertiert den "Amoeba Zeiger" (void *) in (int *) .

    
0x2333 22.03.2017 04:42
quelle

Tags und Links