String-Funktion
-
fit schrieb:
Anscheinend wird der Zeiger bei der Übergabe irgendwie kopiert, obwohl das eigentlich nicht so sein sollte.
auch ein zeiger wird by value uebergeben, oder siehst du irgendwo eine referenz?
-
C Newbie schrieb:
Versuchs mal so:
#include <iostream> #include <string.h> using namespace std; void wait() { cin.clear(); std::cin.ignore(std::cin.rdbuf()->in_avail()); std::cin.get(); }
es würd mich nun sehr intressieren wozu du :
1. einmal cin und einmal std::cin schreibst
2. warum du "using namespace std;" schreibst und dann noch std:: verwendestwirkt irgendwie wien Zwiegespaltener Mensch der Namespaces net verstanden hat.
-
Oh man, in einem C++-Forum noch mit C-Funktionen arbeiten... anstatt dem Neuling mal zu zeigen wie man sicherer und einfacher mit std::string arbeiten kann und sollte.
-
Ähm, dieser Mensch hat ein grundsätzliches Verständnisproblem mit Zeigern. Ich glaube nicht, dass man dem abhelfen kann, indem man sagt, befass dich erstmal mit der string-Klasse und frag in einem halben Jahr dieselbe Frage nochmal ...
-
Hi,
Oh man, in einem C++-Forum noch mit C-Funktionen arbeiten... anstatt dem
Neuling mal zu zeigen wie man sicherer und einfacher mit std::string arbeiten
kann und sollte.Du hast Recht, wie gut dass du gleich ein Beispiel gebracht hast...
Hier ein Beispiel:
void SetzeString(std::string &Str) { Str = "irgendwas"; } std::string MeinString; SetzeString(MeinString);
mfg
v R
-
Shade Of Mine schrieb:
fit schrieb:
Anscheinend wird der Zeiger bei der Übergabe irgendwie kopiert, obwohl das eigentlich nicht so sein sollte.
auch ein zeiger wird by value uebergeben, oder siehst du irgendwo eine referenz?
Jo, aber der Zeiger müsste doch dann aber trotzdem auf die gleiche Adresse im Speicher zeigen, wieso tut er das aber bei 1) und 2) nicht :
#include <iostream.h> #include <string.h> void SetzeString(char* s) { delete s; s = new char[strlen("abcd") +1]; strcpy(s, "abcd"); cout << "2) Adresse von s: " << &s <<endl; } int main() { char* s = "leer"; cout << "1) Adresse von s: " << &s <<endl; SetzeString(s); cout << s << endl; cin.get(); return 0; }
So funzt es dann wieder:
void SetzeString(char*& s) { delete s; s = new char[strlen("abcd") +1]; strcpy(s, "abcd"); cout << "2) Adresse von s: " << &s <<endl; }
-
Wow!
So schnell so viele Antworten! Danke!
Aber leider hat mir keine so wirklich 100% bis jetzt geholfen. *g*
Bashar schrieb:
Ähm, dieser Mensch hat ein grundsätzliches Verständnisproblem mit Zeigern. Ich glaube nicht, dass man dem abhelfen kann, indem man sagt, befass dich erstmal mit der string-Klasse und frag in einem halben Jahr dieselbe Frage nochmal ...
Genau das habe ich und jetzt ist dieses halbe Jahr rum.
Mit std::string ist das kein Problem, aber ich will es jetzt OHNE lösen.
fit schrieb:
... s = new char[strlen("abcd") +1]; ...
An diese Methode hab ich auch schon gedacht, aber dann muss ich ja außerhalb der Funktion wieder delete aufrufen, und gerade das will ich ja umgehen! Ich möchte, dass s nur im Gültigkeitsbereich der die Funktion aufrufenden Routine liegt und nicht auf dem Heap.
-
fit schrieb:
Shade Of Mine schrieb:
auch ein zeiger wird by value uebergeben, oder siehst du irgendwo eine referenz?
Jo, aber der Zeiger müsste doch dann aber trotzdem auf die gleiche Adresse im Speicher zeigen, wieso tut er das aber bei 1) und 2) nicht :
void SetzeString(char* s) { delete s; s = new char[strlen("abcd") +1]; strcpy(s, "abcd"); cout << "2) Adresse von s: " << &s <<endl; }
Du weist innerhalb der Funktion an s einen neuen Wert zu (s = new ...). Da s by-value übergeben wird, ändert sich dadurch nur die lokale Kopie von s. Der Pointer ausserhalb der Funktion wird nicht verändert -> Speicherleck.
Bloops schrieb:
Aber leider hat mir keine so wirklich 100% bis jetzt geholfen. *g*
Dann stell nochmal spezifische Fragen. Genug Antworten hast du ja bekommen.
-
Also im Prinzip gehts um folgendes (vielleicht ist das ja mit C++ auch gar nicht möglich...):
void func1(char *s) { // Größe des Strings, auf den s zeigt auf n Bytes einstellen } void func2(void) { char *string; func1(char); // 1. der String auf den string zeigt, soll nun n Bytes haben // 2. in dieser Funktion (func2) soll KEIN new / delete verwendet werden // 3. string soll NUR in func2 Gültigkeit haben, danach soll der Speicher wieder freigegeben werden. }
Wie muss func1 aussehen, damit func2 so stehen bleiben kann? Geht das überhaupt?
-
... es funktioniert, man muss nur ausreichend Zeiger verwenden
-
// 1. der String auf den string zeigt, soll nun n Bytes haben
// 2. in dieser Funktion (func2) soll KEIN new / delete verwendet werdenDu musst aber new/delete verwenden, wenn string nun n Bytes belegen soll
So geht es:void SetzeString(char*& s) { delete[] s; s = new char[strlen("abcd") +1]; strcpy(s, "abcd"); }
// 3. string soll NUR in func2 Gültigkeit haben, danach soll der Speicher wieder freigegeben werden.
dann halt so:
void SetzeString(char*& s) { s = new char[strlen("abcd") +1]; strcpy(s, "abcd"); //...code... delete[] s; }
-
nein. nicht mit einem einfachen dummen pointer. entweder nimm einen smart pointer oder std::string.
-
PeterTheMaster schrieb:
nein. nicht mit einem einfachen dummen pointer. entweder nimm einen smart pointer oder std::string.
smart pointer? Was ist das?
std:string möchte ich nicht verwenden (s. weiter oben)
fit schrieb:
void SetzeString(char*& s) { s = new char[strlen("abcd") +1]; strcpy(s, "abcd"); //...code... delete[] s; }
Also die Funktion SetzeString entspricht ja der func1 in meinem vorherigen Posting. Wenn ich das jetzt aber so mache, dann wird s ja bereits in func1 zerstört. Es soll aber erst am Ende von func2 zerstört werden. Wenn ich das nun am Ende von func2 mit delete mache, dann hab ich das Problem, dass meine Funktion nicht für andere Benutzer transparent ist, denn woher sollen die wissen, dass sie auf einmal delete nach der Funktion aufrufen müssen...?
Hm... ist alles etwas schwer zu formulieren... ich hoffe, ihr versteht, wo mein Problem liegt.
-
Ja, dein Problem liegt darin, dass du in einem Traum-Universum lebst. Was du vorhast geht schlicht und einfach nicht, genauso wie 1 + 1 niemals 3 wird. Irgendwer muß ja die Verantwortung haben, den Speicher, den der String belegt, freizugeben. Das kann man entweder per Hand machen (mit delete) oder sich eine Klasse schreiben, die das im Destruktor tut (das wär dann std::string.)
-
Aso, das soll erst in funk2 gelöscht werden - habe ich falsch gelesen.
Dann machst du halt am ende von funk2 das delete[] s;Transparent ist das dann schon, denn Du gibst es ja selbst als Bedingung an:
Es soll aber erst am Ende von func2 zerstört werden
Oder anders: Programmiere in Java - da gibts einen Garbage Collector, der gibt automatisch den Speicher wieder frei, wenn die Referenzen auf das gew. Objekt nicht mehr benutzt werden und Du brauchst Dich nicht mehr um delete zu kümmern.
-
Bashar schrieb:
Ja, dein Problem liegt darin, dass du in einem Traum-Universum lebst. Was du vorhast geht schlicht und einfach nicht, genauso wie 1 + 1 niemals 3 wird. Irgendwer muß ja die Verantwortung haben, den Speicher, den der String belegt, freizugeben. Das kann man entweder per Hand machen (mit delete) oder sich eine Klasse schreiben, die das im Destruktor tut (das wär dann std::string.)
Genau das wollte ich ja nur wissen.
Wie schon gesagt, hab bisher größtenteils nur mit PHP programmiert und da geht so etwas ausgezeichnet.Aber danke, für die Mühe, die ihr euch gemacht habt!
Bloops
-
In PHP geht das überhaupt nicht, da gibts nämlich keine char-Pointer.
-
Ja eben! Da geht es noch viel einfacher mit ner ganz normalen Mir-ist-doch-egal-was-ich-für-ein-Typ-bin-Variable
-
Wieso sagst du dann, dass du die string-Klasse nicht benutzen willst?
-
Weil string nur ANSI und nicht UNICODE ist oder hab ich da nen Denkfehler...? kann auch sein.