www.mikrocontroller.net

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


Autor: Pointer auf char Array (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Leute,

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

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

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...

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ja weil du ein zeiger auf ein zeiger brauchst.
void fat16_fread(uint32_t cluster, unsigned char **buffer){
     [....]
     *buffer = mmc_read_sector(cluster); //zeigt auf den 512 Byte großen Speicher 
}

int main(void){
    unsigned char *buffer;
    uint16_t i = 0;  
    fat16_fread(2, &buffer);
    for(i = 0; i < 512; i++){
       printf("%c", buffer[i]); //hier wird nur Müll ausgegeben
    }
}


Autor: Pointer auf char Array (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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
void foo( int * arg )
{
  *arg = 5;
}

int main()
{
  int i;

  foo( &i );
  // an dieser Stelle hat i den Wert: 5
}

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
void foo( T * arg )
{
  *arg =  irgendein_Wert_aus_T;
}

int main()
{
  T variable;

  foo( &variable );
  // an dieser Stelle hat variable den Wert: irgendein_Wert_aus_T
}

soweit so gut.

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

Du erhältst
void foo( char * * arg )
{
  *arg = ein_gültiger_char_pointer;
}

int main()
{
  char * variable;

  foo( &variable );
  // an dieser Stelle hat variable den Wert: ein_gültiger_char_pointer
}

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.

Autor: Pointer auf char Array (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :)

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.