2017-01-31 16 views
1

zurückgegeben werden. Ich möchte mithilfe einer Funktion einem Zeiger Speicher zuweisen. Im Anschluss ist der Code, den ich geschrieben habe:Speicher kann nicht innerhalb einer Funktion zugewiesen und in C

#include <stdio.h> 
#include <stdlib.h> 

int test(unsigned char **q) 
{ 
    *q = (unsigned char *) malloc(250); 
    if(*q == NULL) 
    { 
     printf("\n Error: failed to allocate memory"); 
     return -1; 
    } 
// *q[0] = 10; 
// *q[1] = 10; 
    *q[2] = 10; 

    return 0; /* Returns 0 on success, non-zero value on failure */ 
} 

int main(void) 
{ 
    unsigned char *p; 

// printf("\n &p = %u", &p); 
    int result = test(&p); 

// printf("\n p[2] = %d", p[2]); 
    return 0; 
} 

Wenn ich etwas in *q[0] oder *q[1] schreiben, gibt es keinen Fehler. Aber wenn ich versuche, etwas in *q[2] zu schreiben, gibt es "Segmentation fault (core dumped)".

Auch ich bekomme alle Daten als 0 mit p[ ] außer p[0].

Was ist falsch an diesem Code?

+2

Willkommen bei Stack Overflow! [Bitte lesen Sie die Diskussion darüber, warum der Rückgabewert von 'malloc()' und die Familie in 'C' nicht umgewandelt werden soll.] (Http://stackoverflow.com/q/605845/2173917). –

+6

'* q [2] = 10;' sollte sein '(* q) [2] = 10;'. – mch

+0

Mangel an Wissen! = Typo. Abstimmung zum erneuten Öffnen Fühlen Sie sich frei, als dupe zu schließen. –

Antwort

0

Anstelle dieser falschen Zuordnung

*q[2] = 10; 

, die dem Operator Vorrang entspricht

*(q[2]) = 10; 

zurückzuführen ist und als die dereferenzierten Zeiger q führen [2] ist nicht initialisierten und unbestimmten Wert hat. Sie sollten entweder wie

(*q)[2] = 10; 

oder auch nur wie

q[0][2] = 10; 

Ein anderer Weg, um eine Zwischengröße schreiben und einzuführen, ist zu verwenden Elemente des Arrays zu initialisieren. Zum Beispiel

char *p = *q; 

p[2] = 10; 

Dies ermöglicht es, diese Art von Fehlern mit Zeigern zu entkommen.

+0

Und machen Sie keinen Fehler beim Hinzufügen von Zwischenvariable p vor dem Zuweisen von Speicher. – mk09

2

Aufgrund des Fehlens expliziter Klammern und somit der Standardausgabe operator precedence wird Ihr Ausdruck falsch interpretiert.

Für einen Ausdruck wie

*q[2] 

als

*(q[2]) 

interpretiert wird, das, was Sie nicht wollen, ist hier. Pointer-Arithmetik ehrt den Datentyp, so, x + 1 oder x[1] wird unterschiedliche Ergebnisse haben, wenn

  • x Typ ist char *
  • x vom Typ char **.

Sie benötigen

(*q)[2] = 10; 

ausdrücklich zu schreiben, zuerst zu dereferenzieren die q die char *, zu bekommen und dann verwenden Sie die Indizierung der char zu erhalten.

2

Aufgrund der Vorrangstellung des Bedieners der Sprache C für *q[2], [] wird der Operator vor dem Operator * ausgewertet.

Also *q[2] ist der Wert bei Adresse q + 2. Was Sie wollen, ist der Wert *q + 2. Verwenden Sie also (*q) + 2.

*q[0] oder *q[1] haben keinen Segmentierungsfehler ergeben, weil die Adressen q + 0, q + 1 Ihrem Prozess zugewiesen wurden.

Die Adresse q + 2 wurde Ihrem Prozess und damit dem Segmentierungsfehler nicht zugeordnet.

+0

Danke. Ihre Antwort erklärt die Argumentation für alle Fehler, die ich bekommen habe. Vlad aus Moskau gab verschiedene Wege um diese Fehler zu vermeiden. Also habe ich diese Antwort akzeptiert. – mk09

Verwandte Themen