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


von Gregor B. (gregor54321)


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?
1
int main(void)
2
{
3
  char buf[30];
4
  *buf = sub();
5
}
6
7
int sub()
8
{
9
  char buffer[30];
10
  buffer = "irgend ein Text";
11
  return *buffer;
12
}

von Bernhard M. (boregard)


Lesenswert?

Das wäre:
1
int main(void)
2
{
3
  char *buf;
4
  buf = sub();
5
}
6
7
char *sub()
8
{
9
  char buffer[30] 
10
  strcpy (buffer, "irgend ein Text");
11
  return buffer;
12
}
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:
1
int main(void)
2
{
3
  char *buf;
4
  buf = sub();
5
}
6
7
char *sub()
8
{
9
  static char buffer[30];
10
  strcpy (buffer, "irgend ein Text");
11
  return buffer;
12
}
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

von P. S. (Gast)


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.
1
int main(void)
2
{
3
  char* buf;
4
  buf = sub();
5
6
  .
7
  .
8
  .
9
10
  free( buf);
11
12
  return( 0);
13
}
14
15
char* sub()
16
{
17
  char* buffer = ( char*) malloc( 30);
18
  strncpy( buffer, "irgend ein Text", 30);
19
20
  return buffer;
21
}

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

Die andere Variante war:
1
int main(void)
2
{
3
  char buf[30];
4
  sub( buf, 30);
5
6
  return( 0);
7
}
8
9
void sub( char* buffer, int size)
10
{
11
  strncpy( buffer, "irgend ein Text", size);
12
}


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

http://www.amazon.de/Programmieren-Reference-Manual-deutscher-Sprache/dp/3446138781/ref=ed_oe_o

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

von P. S. (Gast)


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.

von Bernhard M. (boregard)


Lesenswert?

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

von Sven P. (Gast)


Lesenswert?

Gregor B. wrote:
>
1
> int main(void)
2
> {
3
>   char buf[30];
4
>   *buf = sub();
5
> }
6
> 
7
> int sub()
8
> {
9
>   char buffer[30];
10
>   buffer = "irgend ein Text";
11
>   return *buffer;
12
> }
13
>

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:
1
int main(void) {
2
  char buf[30];
3
  sub(buf);
4
}
5
6
int sub(char *p) {
7
  char buffer[30];
8
  buffer = "irgend ein Text";
9
10
  strcpy(p, buffer);
11
}

von Gregor B. (gregor54321)


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.

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.