Pointer auf Char Array zurückgeben

Gast #1792823
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...
Gast #1792837
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
}
Gast #1792854
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.
#1792904
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren