C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Rückgabe von String
Goto page 1, 2  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German)
View previous topic :: View next topic  
Author Message
Alexander M374ller
Guest





PostPosted: Tue Dec 23, 2003 9:59 pm    Post subject: Rückgabe von String Reply with quote



Hallo!
Wir sollen für eine eigene Klasse (einfacher binärer Suchbaum)
eine Funktion schreiben, die den Inhalt als String in Tabellenform
zurückgibt (Ausgabe in Konsolen-Fenster). In C++ stellen sich
mir allerdings einige Probleme. Ich habe jetzt versucht, den String
mit Streams zu erstellen, was soweit klappt. Mein Problem ist
jetzt aber, dass ich die Größe des benötigten Speicherplatzes
erst kenne, wenn der ganze Baum dargestellt ist, ich nutze daher
ein sehr großzügig dimensioniertes Array.
Wenn ich ein statisches array in der Funktion verwende, ist das
ungünstig, da nach Beendigung der Funktion nicht mehr gesichert
ist, dass es noch existiert (auch wenn es funktioniert, Ausgabe
direkt mit dem zurückgegebenen Zeiger).
Reserviere ich den Speicher mit new, dann muss ich das mit einem
globalen Zeiger organisieren (den Speicher wieder frei geben, kann
ich ja nicht in der Funktion, da das vor der Ausgabe wäre). Auch
hier muss ich genügend Speicher bereitstellen (ansonten müsste der
String ständig umkopiert werden).
Gibt es da auch bessere Möglichkeiten für die String-Rückgabe?
Danke schon im Voraus für die Antworten.

Ein frohes Weihnachtsfest und einen guten Rutsch ins neue Jahr
wünsch ich euch!
MfG Alex.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Tobias Bell
Guest





PostPosted: Wed Dec 24, 2003 9:41 pm    Post subject: Re: Rückgabe von String Reply with quote



On Tue, 23 Dec 2003 22:59:32 +0100, Alexander Müller <mueale5 (AT) compuserve (DOT) de> wrote:
Quote:
Hallo!
Wir sollen für eine eigene Klasse (einfacher binärer Suchbaum)
eine Funktion schreiben, die den Inhalt als String in Tabellenform
zurückgibt (Ausgabe in Konsolen-Fenster). In C++ stellen sich
mir allerdings einige Probleme. Ich habe jetzt versucht, den String
mit Streams zu erstellen, was soweit klappt. Mein Problem ist
jetzt aber, dass ich die Größe des benötigten Speicherplatzes
erst kenne, wenn der ganze Baum dargestellt ist, ich nutze daher
ein sehr großzügig dimensioniertes Array.
Wenn ich ein statisches array in der Funktion verwende, ist das
ungünstig, da nach Beendigung der Funktion nicht mehr gesichert
ist, dass es noch existiert (auch wenn es funktioniert, Ausgabe
direkt mit dem zurückgegebenen Zeiger).
Reserviere ich den Speicher mit new, dann muss ich das mit einem
globalen Zeiger organisieren (den Speicher wieder frei geben, kann
ich ja nicht in der Funktion, da das vor der Ausgabe wäre). Auch
hier muss ich genügend Speicher bereitstellen (ansonten müsste der
String ständig umkopiert werden).
Gibt es da auch bessere Möglichkeiten für die String-Rückgabe?
Danke schon im Voraus für die Antworten.


Ich kann dir nicht ganz folgen. Was spricht gegen

#include <sstream>

einen Stringstream? Der übernimmt für dich die komplette Resourcenverwaltung.

Quote:
Ein frohes Weihnachtsfest und einen guten Rutsch ins neue Jahr
wünsch ich euch!
MfG Alex.

Gleichfalls wünscht Tobias


--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Heinz Ozwirk
Guest





PostPosted: Thu Dec 25, 2003 9:23 am    Post subject: Re: Rückgabe von String Reply with quote



"Alexander Müller" schrieb im Newsbeitrag news:bsads3$796$1 (AT) ngspool-d02 (DOT) news.aol.com...
: Hallo!
: Wir sollen für eine eigene Klasse (einfacher binärer Suchbaum)
: eine Funktion schreiben, die den Inhalt als String in Tabellenform
: zurückgibt (Ausgabe in Konsolen-Fenster). In C++ stellen sich
: mir allerdings einige Probleme. Ich habe jetzt versucht, den String
: mit Streams zu erstellen, was soweit klappt. Mein Problem ist
: jetzt aber, dass ich die Größe des benötigten Speicherplatzes
: erst kenne, wenn der ganze Baum dargestellt ist, ich nutze daher
: ein sehr großzügig dimensioniertes Array.

Ein "sehr großzügig dimensionierters Array" ist entweder zu groß oder zu klein, aber nie die richtige Lösung.

: Wenn ich ein statisches array in der Funktion verwende, ist das
: ungünstig, da nach Beendigung der Funktion nicht mehr gesichert
: ist, dass es noch existiert (auch wenn es funktioniert, Ausgabe
: direkt mit dem zurückgegebenen Zeiger).

Statische Variablen innerhalb einer Funktion existieren auch nach dem Verlassen der Funktion, und sie behalten ihren Wert. Solche Funktionen aber weder re-entrent noch können sie rekursiv sein.

: Reserviere ich den Speicher mit new, dann muss ich das mit einem
: globalen Zeiger organisieren

Warum? Den Zeiger könnte man an den Aufrufer zurück geben, und der muss den Speicher dann wieder freigeben.
: (den Speicher wieder frei geben, kann
: ich ja nicht in der Funktion, da das vor der Ausgabe wäre). Auch
: hier muss ich genügend Speicher bereitstellen (ansonten müsste der
: String ständig umkopiert werden).
: Gibt es da auch bessere Möglichkeiten für die String-Rückgabe?

std::string

: Ein frohes Weihnachtsfest und einen guten Rutsch ins neue Jahr
: wünsch ich euch!

dto.
Heinz

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Ludwig Pumberger
Guest





PostPosted: Thu Dec 25, 2003 9:37 am    Post subject: Re: Rückgabe von String Reply with quote

Alexander Müller schrieb:

Quote:
Wir sollen für eine eigene Klasse (einfacher binärer Suchbaum)
eine Funktion schreiben, die den Inhalt als String in Tabellenform
zurückgibt (Ausgabe in Konsolen-Fenster). In C++ stellen sich
mir allerdings einige Probleme. Ich habe jetzt versucht, den String
mit Streams zu erstellen, was soweit klappt. Mein Problem ist
jetzt aber, dass ich die Größe des benötigten Speicherplatzes
erst kenne, wenn der ganze Baum dargestellt ist, ich nutze daher
ein sehr großzügig dimensioniertes Array.

Sehr gefährlich weil anfällig für Überläufe.

Quote:
Wenn ich ein statisches array in der Funktion verwende, ist das
ungünstig, da nach Beendigung der Funktion nicht mehr gesichert
ist, dass es noch existiert (auch wenn es funktioniert, Ausgabe
direkt mit dem zurückgegebenen Zeiger).

Darauf sollte man sich nicht verlassen.

Quote:
Reserviere ich den Speicher mit new, dann muss ich das mit einem
globalen Zeiger organisieren (den Speicher wieder frei geben, kann
ich ja nicht in der Funktion, da das vor der Ausgabe wäre). Auch
hier muss ich genügend Speicher bereitstellen (ansonten müsste der
String ständig umkopiert werden).

Warum ein globaler Zeiger? Wenn du einen Zeiger zurückgibst könnte ihn die
aufrufende Funktion freigeben. Das ist aber eher schlechter Stil. In C
APIs ist es üblich einen Zeiger und eine Länge zu übergeben, und die
Funktion füllt den Speicher und liefert einen Fehler falls die Länge nicht
ausreicht.

Quote:
Gibt es da auch bessere Möglichkeiten für die String-Rückgabe?

std::string aus <string>. Da musst du dich um gar nichts kümmern. Der
String wird zwar (wahrscheinlich) herumkopiert werden, aber dafür besteht
keine Fehlergefahr und keine Notwendigkeit mit Zeigern herum zu spielen.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Thomas Maeder
Guest





PostPosted: Thu Dec 25, 2003 9:46 am    Post subject: Re: Rückgabe von String Reply with quote

"Alexander Müller" <mueale5 (AT) compuserve (DOT) de> writes:

Quote:
Wir sollen für eine eigene Klasse (einfacher binärer Suchbaum)
eine Funktion schreiben, die den Inhalt als String in Tabellenform
zurückgibt (Ausgabe in Konsolen-Fenster). In C++ stellen sich
mir allerdings einige Probleme. Ich habe jetzt versucht, den String
mit Streams zu erstellen, was soweit klappt.

Was bedeutet das? Schreibst Du die Inhalte in einen std::ostringstream?


Quote:
Mein Problem ist
jetzt aber, dass ich die Größe des benötigten Speicherplatzes
erst kenne, wenn der ganze Baum dargestellt ist, ich nutze daher
ein sehr großzügig dimensioniertes Array.

std::ostringstream alloziert intern bei Bedarf so viel Speicher, wie
benötigt wird; Du brauchst Dich nicht darum zu kümmern.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Alexander M374ller
Guest





PostPosted: Thu Dec 25, 2003 12:44 pm    Post subject: Re: Rückgabe von String Reply with quote

Danke für die Antworten.
Ich hatte bei dem Stream ursprünglich noch einen
Speicherplatz reserviert und ihn an den Konstruktor
übergeben, hatte dann aber bemerkt, das ich das
weglassen kann.
Die funktionierende Variante, die ich jetzt habe,
sieht folgendermaßen aus (das Problem Zeiger
auf nicht mehr allokierten Speicherbereich ist mir
bewusst)

class BinarySearchTree
{
....
char* toString()
{
ostrstream outStream;
outStream << "irgendwas" << ends;
return outStream.str();
}
}

int main()
{
BinarySearchTree BST;
printf("%s",BST.toString());
return 0;
}

Ersetze ich aber das char* durch std::string, dann
erhalte ich einen Zugriffsfehler (Speicher in 0xcccccccc).
Das passiert auch, wenn ich ostrstream durch das vor-
geschlagene ostringstream ersetze. Wie sieht die Rück-
gabe dann aus?

MfG Alex.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Marco Budde
Guest





PostPosted: Thu Dec 25, 2003 7:37 pm    Post subject: Re: R374ckgabe von Stringn ^ Reply with quote

Alexander Müller wrote:

Quote:
mit Streams zu erstellen, was soweit klappt. Mein Problem ist
jetzt aber, dass ich die Größe des benötigten Speicherplatzes
erst kenne, wenn der ganze Baum dargestellt ist,

(1) Nö, Du könntest den Erzeugealgorithmus zuerst einmal
durchlaufen lassen und nur die benötigte Anzahl von Bytes
ermitteln, dann Speicher allokieren und dann die Algorithmus
ein zweites Mal durchlaufen lassen.

(2) Die Größe des Speichers ist erst zur Laufzeit bekannt,
Du brauchst also dynamischen Speicher (new/delete) auf dem
Heap.

Quote:
ich nutze daher
ein sehr großzügig dimensioniertes Array.

Tu das bitte auf keinen Fall. Genau das ist *der* Grund für viele
Sicherheitsprobleme in aktueller Software, Stichwort "Buffer
Overflow". Ganz übel.

Quote:
Wenn ich ein statisches array in der Funktion verwende, ist das
ungünstig, da nach Beendigung der Funktion nicht mehr gesichert
ist, dass es noch existiert (auch wenn es funktioniert, Ausgabe
direkt mit dem zurückgegebenen Zeiger).

Richtig, deswegen dynamischen Speicher verwenden.

Quote:
Reserviere ich den Speicher mit new, dann muss ich das mit einem
globalen Zeiger organisieren

Auf keinen Fall! Es gibt in C++ so gut wie keinen Grund, irgend-
etwas global anzulegen. Als Anfänger kannst Du Dir erst einmal
merken: global ist immer falsch.

Quote:
(den Speicher wieder frei geben, kann
ich ja nicht in der Funktion, da das vor der Ausgabe wäre).

Warum muß der Zeiger deswegen global sein?

char *baum_erzeugen()
{
char *ret;

...

ret = new char[1000];

...

return (ret);
}


int main()
{
char *baum;

baum = baum_erzeugen();
cout << baum;
delete [] baum;
}

Allerdings ist es eher selten sinnvoll, Speicher in einer Funktion
zu allokieren und außerhalb wieder freizugeben (wird gerne vergessen
-> Speicherleck).

Quote:
Gibt es da auch bessere Möglichkeiten für die String-Rückgabe?

Ja, ich würde einfach mal einen Blick in ein vernünftiges C++ Buch
werfen (versuche erst garnicht, C++ ohne Buch zu lernen, das wird
nichts).

Du willst die Klasse std::string aus der Standard C++ Bibliothek
benutzen. Dann sieht das so aus:

void baum_erzeugen (std::string &baum)
{
}


Frohes Fest,

Marco
--
S: Minolta: Winkelsucher (VN), VC-9

E-Mail: mb-news-b<ät>linuxhaven.de
Deutsches Linux HOWTO Projekt: http://www.linuxhaven.de

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Rolf Magnus
Guest





PostPosted: Fri Dec 26, 2003 9:33 am    Post subject: Re: Rückgabe von String Reply with quote

Ludwig Pumberger wrote:

Quote:
Wenn ich ein statisches array in der Funktion verwende, ist das
ungünstig, da nach Beendigung der Funktion nicht mehr gesichert
ist, dass es noch existiert (auch wenn es funktioniert, Ausgabe
direkt mit dem zurückgegebenen Zeiger).

Darauf sollte man sich nicht verlassen.

Wenn es static ist, ist sehr wohl sicher, daß es noch existiert.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Ludwig Pumberger
Guest





PostPosted: Fri Dec 26, 2003 11:49 am    Post subject: Re: Rückgabe von String Reply with quote

Rolf Magnus schrieb:

Quote:
Wenn ich ein statisches array in der Funktion verwende, ist das
ungünstig, da nach Beendigung der Funktion nicht mehr gesichert
ist, dass es noch existiert (auch wenn es funktioniert, Ausgabe
direkt mit dem zurückgegebenen Zeiger).

Darauf sollte man sich nicht verlassen.

Wenn es static ist, ist sehr wohl sicher, daß es noch existiert.


Wenn es static ist schon. Nur bei statisch denke ich in Zusammenhang mit
Arrays zuererst einmal an nicht-dynamisch. Ein wirklich static-statisches
Array könnte in multithreaded Programmen zum Problem werden.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Thomas Maeder
Guest





PostPosted: Fri Dec 26, 2003 4:31 pm    Post subject: Re: Rückgabe von String Reply with quote

"Alexander Müller" <mueale5 (AT) compuserve (DOT) de> writes:

Quote:
Die funktionierende Variante, die ich jetzt habe,
sieht folgendermaßen aus (das Problem Zeiger
auf nicht mehr allokierten Speicherbereich ist mir
bewusst)

class BinarySearchTree
{
...
char* toString()

toString()-Funktionen verändern das Objekt, auf das sie angewendet werden,
in aller Regel nicht. Du solltest diese Funktionen deshalb const deklarieren.


Quote:
{
ostrstream outStream;
outStream << "irgendwas" << ends;
return outStream.str();
}
}

int main()
{
BinarySearchTree BST;
printf("%s",BST.toString());

Diese "Lösung" hat ein Speicherleck. Sobald Du auf einen ostrstream die
Memberfunktion str() anwendest, bist "Du" (d.h. der Aufrufende) dafür
zuständig, den Speicherbereich freizugeben, auf den der Rückgabewert
zeigt.

Ich würde in neuem Code nie eine *strstream-Klasse verwenden, sondern immer
eine *stringstream-Klasse. Letztere haben den Vorteil, dass str() ein
std::string-Objekt zurückgibt, welches den benötigten Speicher im richtigen
Moment freigibt:

#include #include <iostream>
#include <sstream>
#include <ostream>

class BinarySearchTree
{
std::string toString() const
{
std::ostringstream outStream;
outStream << "irgendwas";
return outStream.str();
}
}

int main()
{
BinarySearchTree BST;
std::cout << BST.toString();
return 0;
}

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Marco Budde
Guest





PostPosted: Fri Dec 26, 2003 4:42 pm    Post subject: Re: Re: Rückgabe von String Reply with quote

Ludwig Pumberger wrote:

Quote:
Wenn es static ist schon. Nur bei statisch denke ich in Zusammenhang mit
Arrays zuererst einmal an nicht-dynamisch. Ein wirklich static-statisches
Array könnte in multithreaded Programmen zum Problem werden.

Nicht nur dort, auch in Single Thread Programmen kann eine Funktion
mehrfach von verschiedenen Stellen aufgerufen werden.

cu, Marco
--
S: Minolta: Winkelsucher (VN), VC-9

E-Mail: mb-news-b<ät>linuxhaven.de
Deutsches Linux HOWTO Projekt: http://www.linuxhaven.de

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Alexander M374ller
Guest





PostPosted: Sat Dec 27, 2003 1:01 pm    Post subject: Re: Rückgabe von String Reply with quote

Danke!
Jetzt funktioniert es einwandfrei. Mir war bisher noch
nicht klar, dass std::cout und cout etwas anderes sind.
Als ich es nämlich das erste mal mit cout probiert hatte,
hat es den Typ nicht anerkannt. Und für std::cout hatte
ich nicht die richtigen Header eingefügt, wusste aber in
dem Moment auch nicht welche.
Bei dem ostringstream darf kein String-Ende-Zeichen
gesetzt werden, oder?
MfG Alex.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de
Back to top
Rolf Magnus
Guest





PostPosted: Sun Dec 28, 2003 10:09 am    Post subject: Re: Re: Rückgabe von String Reply with quote

Marco Budde wrote:

Quote:
Ludwig Pumberger wrote:

Wenn es static ist schon. Nur bei statisch denke ich in Zusammenhang
mit Arrays zuererst einmal an nicht-dynamisch. Ein wirklich
static-statisches Array könnte in multithreaded Programmen zum
Problem werden.

Nicht nur dort, auch in Single Thread Programmen kann eine Funktion
mehrfach von verschiedenen Stellen aufgerufen werden.

Wie das? Das ginge doch höchstens, wenn die Funktion rekursiv wäre.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Rolf Magnus
Guest





PostPosted: Sun Dec 28, 2003 10:13 am    Post subject: Re: Rückgabe von String Reply with quote

Alexander Müller wrote:

Quote:
Danke!
Jetzt funktioniert es einwandfrei. Mir war bisher noch
nicht klar, dass std::cout und cout etwas anderes sind.
Als ich es nämlich das erste mal mit cout probiert hatte,
hat es den Typ nicht anerkannt. Und für std::cout hatte
ich nicht die richtigen Header eingefügt, wusste aber in
dem Moment auch nicht welche.
Bei dem ostringstream darf kein String-Ende-Zeichen
gesetzt werden, oder?

Dem ostringstream ist es eigentlich egal. Es wird eben ein 'zusätzliches
' am Ende eingefügt, was zwar vermutlich zu keinem Problem führt,
aber auch keinen Vorteil bringt.


PS: Könntest du mal deine Newsreader-Einstellungen reparieren? Dein
charset ist kaputt:

Quote:
Content-Type: text/plain; charset=unknown-8bit

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Thomas Maeder
Guest





PostPosted: Sun Dec 28, 2003 10:21 am    Post subject: Re: Rückgabe von String Reply with quote

"Alexander Müller" <mueale5 (AT) compuserve (DOT) de> writes:

Quote:
Bei dem ostringstream darf kein String-Ende-Zeichen
gesetzt werden, oder?

Ich nehme an, Du meinst std::ends. Ich würde annehmen, dass das nicht geht,
weil die passende operator<<-Überladung fehlt. Sicher ist es nicht sinnvoll,
ends in einen std::ostringstream zu schieben, denn dieser weiss selber, wo
sein Ende ist, und um ein 0-Zeichen reinzuschieben, gibt es eine einfachere
und klarere Möglichkeit.

--
de.comp.lang.iso-c++ - Moderation: mailto:voyager+mod (AT) bud (DOT) prima.de
FAQ: http://www.voyager.prima.de/cpp/ mailto:voyager+send-faq (AT) bud (DOT) prima.de

Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ (German) All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.