www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik pointer auf char[ ] zurück geben


Autor: Gregor B. (gregor54321)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe folgendes Problem:
Ich erzeuge in einem Unterprogramm einen Buffer, der einen String 
enthält. Dieser String soll später an anderer Stelle ausgegeben werden. 
Wie kann ich den String an den Aufrufer übergeben?
Gibts ne EINFACHE Heranführung an die Zeigerthematik im Netz? AVR-Tut 
ist mir irgendwie schon zu kompliziert. Wann muss der Stern wohin?
int main(void)
{
  char buf[30];
  *buf = sub();
}

int sub()
{
  char buffer[30];
  buffer = "irgend ein Text";
  return *buffer;
}

Autor: Bernhard M. (boregard)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das wäre:
int main(void)
{
  char *buf;
  buf = sub();
}

char *sub()
{
  char buffer[30] 
  strcpy (buffer, "irgend ein Text");
  return buffer;
}
funktioniert aber nicht, oder nur zeitweise scheinbar...
weil der Speicher von "buffer" lokal von "sub" ist un damit  auf dem 
Stack liegt, d.h. nach dem verlassen von "sub" wieder beim Aufruf der 
nächsten Funktion überschrieben wird.
Also entweder:
int main(void)
{
  char *buf;
  buf = sub();
}

char *sub()
{
  static char buffer[30];
  strcpy (buffer, "irgend ein Text");
  return buffer;
}
damit der Speiceher statisch angelegt wird (damit ist so eine Funktion 
dann bestimmt nicht re-entrant, das ist aber meist egal, wenn man keine 
Rekursionen oder Multitasking hat - auf dem AVR eher selten..), oder den 
Speicher allozieren (mit malloc..., was auf dem AVR auch nicht immer zu 
empfehlen ist)...

Gruß,
Bernhard

Edit: mitkopierte Fehler korrigiert

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Ich erzeuge in einem Unterprogramm einen Buffer, der einen String
>enthält.

Du erzeugst keinen Buffer. Deine Funktion hat einen lokalen Buffer, 
vermutlich auf dem Stack. Der existiert genau so lange wie dein Aufruf 
dauert. Den darfst du gar nicht zurueckgeben.

Du kannst entweder einen existierenden Buffer uebergeben und den in der 
Funktion fuellen, oder in der Funktion Speicher reservieren (malloc()), 
den fuellen und zurueckgeben - aber die Freigabe nicht vergessen.
int main(void)
{
  char* buf;
  buf = sub();

  .
  .
  .

  free( buf);

  return( 0);
}

char* sub()
{
  char* buffer = ( char*) malloc( 30);
  strncpy( buffer, "irgend ein Text", 30);

  return buffer;
}

In deinem speziellen Fall ginge auch
char* sub()
{
  return( strdup( "irgend ein Text"));
}

Die andere Variante war:
int main(void)
{
  char buf[30];
  sub( buf, 30);

  return( 0);
}

void sub( char* buffer, int size)
{
  strncpy( buffer, "irgend ein Text", size);
}


Immer noch das Standardwerk und am besten von vorne nach hinten 
durchzulesen:

http://www.amazon.de/Programmieren-Reference-Manua...

Ich finde auch, erst mal Assembler zu machen um zu verstehen, was 
Speicher und Pointer ueberhaupt sind, ist immer noch der beste Weg.

Autor: P. S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernhard M. wrote:

> damit der Speiceher statisch angelegt wird (damit ist so eine Funktion
> dann bestimmt nicht re-entrant, das ist aber meist egal, wenn man keine
> Rekursionen oder Multitasking hat - auf dem AVR eher selten..),

Interrupthandler sind wohl eher haeuffig auf AVR, also ist es IMO 
klueger, auf Reentranz zu achten.

Autor: Bernhard M. (boregard)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm gut, ich persönlich käme nicht auf die Idee, solche Sachen im 
Interrupt zu machen, aber gut für den Hinweis.

Autor: Sven P. (haku) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gregor B. wrote:
>
> int main(void)
> {
>   char buf[30];
>   *buf = sub();
> }
> 
> int sub()
> {
>   char buffer[30];
>   buffer = "irgend ein Text";
>   return *buffer;
> }
> 

Kann so nicht gehen, weil das buf[] in der Main-Funktion kein Array ist, 
sondern ein Vektor (JA, das macht einen Unterschied). Außerdem ist 
buffer[] in der Sub-Funktion nach deren Verlassen auch schon wieder weg, 
weils lokal auf dem Stack liegt.
Machs doch direkt mitn Zeiger:
int main(void) {
  char buf[30];
  sub(buf);
}

int sub(char *p) {
  char buffer[30];
  buffer = "irgend ein Text";

  strcpy(p, buffer);
}

Autor: Gregor B. (gregor54321)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke erstmal allen für die - erschreckend vielseitigen - Lösungen zum 
Problem. Ich hab mir das vorgeschlagene Buch als "Used-Edition" über die 
Amazonen geordert.
@Sven Pauli: Das man das Array "abschickt", aber einen Zeiger darauf 
empfangen kann, wusste ich bisher auch noch nicht. Ich hoffe, das Buch 
wird mir Einsichten schenken.

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.