Wie const char* myFunc()?
-
Hi,
mich interessiert mal ein brennend. Wie ist die Rückgabegeschichte mit "const char *" in der STL realisiert?
Wenn ich z.B. :
const char *myFunc() { std::string Blub = "Blub"; return Blub.c_str(); }ausführe, ist mein "Blub" nach dem Aufruf nicht mehr gültig. Ist ja auch logisch, da "std::string::c_str()" nur einen Pointer auf den Inhalt des lokalen Objekts liefert.
Also wie wurde das umgesetzt? Nehmen wir als Beispiele mal:
"const char *std::exception::what()" oder "const char *std::string::c_str()".Ein Danke, jetzt schon mal.
-
Klassenmethoden wie c_str() oder what() liefern normalerweise einen Zeiger auf interne Daten des this-Objekts. Ansonsten kannst du auch ein static char-Array zurückgeben oder den Speicher per new anfordern (in dem Fall wäre der Aufrufer verantwortlich, den Speicher freizugeben).
(und in C++ ist sowas sowieso unüblich - gibt lieber den zusammengebauten std::string aus anstelle seines char*-Puffers)
-
Die benutzen ein Member.
Wenn Du eine Klasse hast, die so aussieht:class Test { public: const char* what() const {return text.c_str();} private: std::string text; };kannst Du es genauso machen.
-
Bei string::c_str() existiert das string-Objekt ja und gibt nur einen Zeiger auf seinen eigenen Speicher-Inhalt zurück. Der ist dann halt gültig, solange das string-Objekt existiert. Bei deiner Funktion geht ja das string-Objekt beim Ende der Funktion kaputt, dann ist der Zeiger nicht mehr gültig. Das selbe gilt für exception::what(), das hat intern halt auch einen string und solange die exception und damit auch der string darin existiert, ist auch der const char*-Zeiger gültig, den du bekommst

-
Hmm, also so was ähnliches hatte ich mir schon gedacht. Danke schön.

-
CStoll schrieb:
...und in C++ ist sowas sowieso unüblich - gibt lieber den zusammengebauten std::string aus anstelle seines char*-Puffers
Zu Recht, weil es diese ganezn "Ownership-Probleme" damit gibt. Als Außenstehender weiß ich ja gar nicht, ob ich deleten muss oder nicht darf oder das Zeug überhaupt noch gültig ist....
vector<char*> glob; struct A { // verschiedenen Formen von "interner char-Verwaltung" char* internDynBuffer; char internBuffer; string isInit_Dyn; static char* staticDynBuffer; string isInit; static char staticBuffer[100]; size_t globIndex; A() { strncpy(internBuffer, "Simon2", 100); internDynBuffer = new char[100]; strncpy(internDynBuffer, "Simon2", 100); if(isInit_Dyn == "") { staticDynBuffer = new char[100]; strncpy(staticDynBuffer, "Simon2", 100); isInit_Dyn = "true"; } if(isInit == "") { strncpy(staticBuffer, "Simon2", 100); isInit = "true"; } globIndex = glob.size(); glob.push_back(new char[100]); strncpy(glob[globIndex], "Simon2", 100); } char* get1() const { return internDynBuffer; } char* get2() const { return internBuffer; } char* get3() const { return staticDynBuffer; } char* get4() const { return staticBuffer; } char* get5() const { return glob[globIndex]; } char* get6() const { return "Simon2"; } }; void fill(A const& a, vector<char*>& v) { v.push_back(a.get1()); v.push_back(a.get2()); v.push_back(a.get3()); v.push_back(a.get4()); v.push_back(a.get5()); v.push_back(a.get6()); } int main() { A a; vector<char*> v; fill(a, v); { B b; fill(a, v); } delete v[....// Naaaaa ? Welche sollen/müssen wir denn jetzt löschen ? Welche sind überhaupt gültig ?
Leider bringen Pointer diese Informationen nicht mit ... weswegen Konstrukte, die das selbst organisieren (z.B. shared-"der Letzte macht das Licht aus"-pointer aber auch std::string), besser sind.
Gruß,
Simon2.