Forum: Mikrocontroller und Digitale Elektronik Pointer auf Char Array zurückgeben


von Pointer auf char Array (Gast)


Lesenswert?

Hi Leute,

ich hab folgende Funktionen:
1
unsigned char* mmc_read_sector(uint16_t addr){
2
     static unsigned char buffer[512];
3
     [....]
4
     return buffer;
5
}
1
void fat16_fread(uint32_t cluster, unsigned char *buffer){
2
     [....]
3
     buffer = mmc_read_sector(cluster); //zeigt auf den 512 Byte großen Speicher 
4
}

Hauptprogramm:
1
int main(void){
2
    unsigned char *buffer;
3
    uint16_t i = 0;  
4
    fat16_fread(2, buffer);
5
    for(i = 0; i < 512; i++){
6
       printf("%c", buffer[i]); //hier wird nur Müll ausgegeben
7
    }
8
}

In der Funktion mmc_read_sector hab ich das Char-Array als static 
definiert, damit der Speicher auf dem Stack nach Beendigung der Funktion 
nicht wieder freigegeben wird.
Doch wenn ich im Hauptprogramm den Inhalt von buffer ausgebe (der 
Pointer sollte ja auf den 512 Byte große char-Array zeigen?), dann 
erhalte ich nur Datenmüll.
Ich hoffe ihr könnt mir helfen, ich hab hier glaub ich grad ein riesiges 
Brett vorm Kopf...

von Peter (Gast)


Lesenswert?

ja weil du ein zeiger auf ein zeiger brauchst.
1
void fat16_fread(uint32_t cluster, unsigned char **buffer){
2
     [....]
3
     *buffer = mmc_read_sector(cluster); //zeigt auf den 512 Byte großen Speicher 
4
}
5
6
int main(void){
7
    unsigned char *buffer;
8
    uint16_t i = 0;  
9
    fat16_fread(2, &buffer);
10
    for(i = 0; i < 512; i++){
11
       printf("%c", buffer[i]); //hier wird nur Müll ausgegeben
12
    }
13
}

von Pointer auf char Array (Gast)


Lesenswert?

Danke, es funktioniert!

Also das mit dem Zeiger auf einen Zeiger muss ich mir nochmal in Ruhe in 
einem C-Buch anschauen, so 100% klar ist mir das nicht, warum ich das 
hier brauche.

von Karl H. (kbuchegg)


Lesenswert?

Pointer auf char Array schrieb:
> Danke, es funktioniert!
>
> Also das mit dem Zeiger auf einen Zeiger muss ich mir nochmal in Ruhe in
> einem C-Buch anschauen, so 100% klar ist mir das nicht, warum ich das
> hier brauche.

Einen Schritt zurücktreten.

Wenn du eine Funktion hast, die beim Aufrufer einen int verändern 
möchte, dann braucht die Funktion einen Pointer auf diesen int
1
void foo( int * arg )
2
{
3
  *arg = 5;
4
}
5
6
int main()
7
{
8
  int i;
9
10
  foo( &i );
11
  // an dieser Stelle hat i den Wert: 5
12
}

Soweit dürfte das noch klar sein. Das findet sich in allen Lehrbüchern 
relativ weit vorne und ist meistens der erste Kontakt eines C-Lernenden 
mit Pointern.

Allgemeiner ausgedrückt kann man sagen.
Wenn jemand eine Funktion in die Lage versetzen möchte, eine Variable 
vom Datentyp T bei sich zu verändern, dann sieht das allgemeine Schema 
so aus
1
void foo( T * arg )
2
{
3
  *arg =  irgendein_Wert_aus_T;
4
}
5
6
int main()
7
{
8
  T variable;
9
10
  foo( &variable );
11
  // an dieser Stelle hat variable den Wert: irgendein_Wert_aus_T
12
}

soweit so gut.

Und jetzt nimmst du dieses Schema her, und ersetzt T durch char *, also 
einen Pointer of char.

Du erhältst
1
void foo( char * * arg )
2
{
3
  *arg = ein_gültiger_char_pointer;
4
}
5
6
int main()
7
{
8
  char * variable;
9
10
  foo( &variable );
11
  // an dieser Stelle hat variable den Wert: ein_gültiger_char_pointer
12
}

Grob gesagt: Um diese angestrebte Funktionalität zu erreichen (nämlich 
eine Variable beim Aufrufer zu verändern), brauchst du

a) in der Argumentliste immer 1 Stern mehr, als der Datentyp der
   Variablen um die es geht.
   bei int    ist es eben ein int *
   bei long   ist es eben ein long *
   bei char*  ist es eben ein char **

b) im Aufruf einen &, damit der Aufrufer die Adresse der Variablen
   übergibt, deren Inhalt geändert werden soll.

c) Innerhalb der Funktion einen Dereferenzier-* wenn auf den Inhalt
   der 'übergebenen' Variablen zugegriffen werden soll. Die Variable
   wird ja nicht wirklich übergeben, sondern deren Speicher-Adresse.

von Pointer auf char Array (Gast)


Lesenswert?

Die Erklärung ist ausgezeichnet, danke! Jetzt hab ichs verstanden.

Den Thread muss ich mir gleich bookmarken, so ne gute Erklärung findet 
man kaum :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.